对象【回顾】

通过字面量创建对象

//通过字面量创建对象
var obj1 = {
name:'Jack',
age: 18
}

通过系统自带的构造函数构造对象

// 通过系统自带的构造函数构造对象
// 其他构造函数有:new Array(),new Number,new Date(),new Boolean()
var obj2 = new Object();
obj2.name = 'Jack';
obj2.age = 18;

通过自定义函数构造对象

// 通过自定义函数构造对象
// 为了和普通函数区别,构造函数命名首字母要大写(帕斯卡命名法)
function Obj3(name,age) {
this.name = name;
this.age = age;
this.sayHi = function () {
alert(this.name)
};
}
var dx1 = new Obj3('Jack', 18);
var dx2 = new Obj3('Brush', 18);

扩展之new关键字

  首先,我先说下自定义构造函数创建对象的基本流程,使用new和不适用new差别很大,不用new的话,则Obj3(name)就作为一个普通的函数执行(只是函数名的首字母大写了),没有返回值,那么默认返回的是undefined,而用new关键字后,JS就会把该函数作为一个构造函数看待,经过一系列的隐式操作,返回值是一个对象了。

  new关键字的“隐式操作”:

    ①在内存中创建一个空的Object类型的对象----看不到

    ②让this关键字指向这个空的对象(将构造函数的作用域赋给新对象)----看不到

// ① ② 的执行过程
var this = Object.creat(Obj3.prototype);
// this 指向 Obj3.prototype(后面讲到)
// 可以看出构造函数创建对象的最根本原理是借用Object.create()方法来实现的,只不过被封装功能化了

    在前面的例子中,dx1和dx2分别保存着Obj3的一个不同的实例。这俩个对象都有有一个constructor(构造函数)的属性,该属性指向Obj3,如下:

console.log(dx1.constructor  == Obj3) // true
console.log(dx2.constructor == Obj3) // true  

    对象的constructor属性最初用来表示对象类型的。但是,检测对象类型,还是instanceof操作符要更可靠一些-----用来检测一个对象在其原型链中,是否存在一个构造函数的prototype属性。

    我们在这个例子中创建的所有对象即使Object的实例,同时也是Obj3的实例,这一点可以通过instanceof操作符可以得到验证。

    console.log(dx1 instanceof Obj3);  // true
console.log(dx1 instanceof Object); // true
console.log(dx2 instanceof Obj3); // true
console.log(dx2 instanceof Object); // true
// dx1 和 dx2 之所以同时是Object的实例,是因为所有的对象均继承自Object

  ③通过this给这个对象添加属性和方法---看得见

// this.name = 'Jack';
this.age = 18;

  ④将这个对象返回给用new关键字调用的构造函数Obj3(name)的调用者(dx1)

return this;

注:Object在JS中,所有不同类型的对象,都直接或间接的集成于它。

原型对象和原型链

原型

  我们所创建的每一个函数都有一个 prototype (原型)的属性,这个属性是一个指针,指向一个对象,而这个对象的用途包含可以由特定类型的所有实例共享的属性和方法。

  那么prototype就可以通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。换句话说,不必在构造函数中描述对象实例的全部信息,而是可以将这些信息直接添加到原型对象中去,那么上面的Obj3()函数就可以写成这样:

function Obj3(name, age) {
this.name = name
this.age = age
}
Obj3.prototype.sayHi = function () {
alert(this.name)
}
var dx1 = new Obj3('Jack', 18)
// 用于测试一个对象是否存在于另一个对象的原型链上。
// prototypeObj.isPrototypeOf(object) // 在object的原型链上搜寻 返回 布尔值
console.log(Obj3.prototype.isPrototypeOf(dx1)) // true
// obj.hasOwnProperty(prop) 方法会返回一个布尔值,判断自身属性是否存在,无法判断继承(prototype)属性
console.log(dx1.hasOwnProperty('name')) // true
console.log(dx1.hasOwnProperty('sayHi')) // false

var dx2 = new Obj3('Brush', 18)

  在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。就拿上面的例子来说, Obj3.prototype.constructor指向Obj3。而通过Obj3这个构造函数,我们还可以继续为原型对象添加其他属性和方法。

  当构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型方法。在每一个对象都支持一个属性:"__ proto __"。

  我们可以通过isPrototype()方法来确定对象之间是否存在这个关系。从本质上讲,如果[Prototype]指向调用isPrototype()方法的对象(Obj3.prototype),那么这个方法就返回true。

  使用hasOwnProperty()可以检测一个属性是否存在在实例中,还是存在在原型中。这个方法(从Object继承来的)只是给定属性存在在对象实例中,才会返回true;存在在原型中,返回false。

原型对象的原型

所有的原型应用类型(Object、Array、String)都在其构造函数的原型上定义了方法。

在Array.prototype中可以找到sort()方法;

在String.prototype中可以找到substring()方法,如下:

console.log(Array.prototype.sort); // ƒ sort() { [native code] }
console.log(String.prototype.substring); // ƒ substring() { [native code] }

原型链

  原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。如果,我们让这个原型对象等于另一个类型的实例,显然,此时的原型对象包含一个指向另一个原型的指针,相应的,另一个原型中野包含着指向另另一个类型的实例,那么,层层递进,就构成了实例与原型的链条,这就是原型链的基本概念。

  我们知道,所有引用类型默认都继承了Object,而这个继承也是通过原型链实现的。所有函数的默认原型都是Object的实例,因此默认原型都包含一个内部指针,指向Object.prototype。这正是所有自定义类型都会继承toString()、valueOf()等默认方式的根本原因。

function Obj3(name, age) {
this.name = name
this.age = age
}
Obj3.prototype.sayHi = function () {
alert(this.name)
}
var dx1 = new Obj3('Jack', 18)
console.log(dx1.constructor)
console.log(dx1.constructor.constructor)
console.log(dx1.constructor.constructor.prototype)
console.log(dx1.constructor.constructor.prototype.__proto__.__proto__)

结果:

JavaScript 之 原型及原型链的更多相关文章

  1. JavaScript之继承(原型链)

    JavaScript之继承(原型链) 我们知道继承是oo语言中不可缺少的一部分,对于JavaScript也是如此.一般的继承有两种方式:其一,接口继承,只继承方法的签名:其二,实现继承,继承实际的方法 ...

  2. 【javascript基础】4、原型与原型链

    前言 荒废了好几天,在宿舍闷了几天了,一直想着回家放松,什么也没搞,论文就让老师催吧.不过,闲的没事干的感觉真是不好,还是看看书,写写博客吧,今天和大家说说函数的原型. 原型是什么 第一次看到这个的时 ...

  3. 【JavaScript】深入理解JavaScript之强大的原型和原型链

    由于JavaScript是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的,今天我们就来了解一下原型和原型链. AD: hasOwnProperty函数: hasOw ...

  4. 《JavaScript 闯关记》之原型及原型链

    原型链是一种机制,指的是 JavaScript 每个对象都有一个内置的 __proto__ 属性指向创建它的构造函数的 prototype(原型)属性.原型链的作用是为了实现对象的继承,要理解原型链, ...

  5. Javascript 原型和原型链

    先来了解一下Javascript中的原型:”原型也是一个对象,原型可以用来实现继承...“ 对于 原型,构造函数,以及实例之间的关系:“每个(构造)函数都有一个原型属性,原型对象都包含一个指向构造函数 ...

  6. javascript 原型 和 原型链

    最近几天,好些新同事来问原型,原型链啥的.本身作为菜鸟的我好像也没有好好整理过这个,这里写写自己的理解. 原型 大家都知道,JavaScript 不包含传统的类继承模型,而是使用 prototype ...

  7. JavaScript深入之从原型到原型链(本文转载)

    JavaScript深入之从原型到原型链(本文转载) https://github.com/mqyqingfeng/Blog.原文地址 构造函数创建对象 我们先使用构造函数创建一个对象: functi ...

  8. javascript 之原型、原型链-14

    原型 原型是一个对象,每个函数对象(在javascript 之对象中说过函数也是对象 )都有一个属性(prototype)指向这个对象--原型对象,这个对象的作用是让所有对象实例共享原型对象中的属性. ...

  9. JavaScript原型与原型链

    一.数据类型 JavaScript的数据类型可以分为基本数据类型和引用数据类型. 基本数据类型(6种) String Number Boolean null undefined Symbol(ES6) ...

  10. JavaScript prototype原型和原型链详解

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

随机推荐

  1. 05.swoole学习笔记--定时器

    <?php //循环执行的定时器 swoole_timer_tick(,function($timer_id){ echo "执行 $timer_id \n"; }); sw ...

  2. 13.在项目中部署redis企业级数据备份方案以及各种踩坑的数据恢复容灾演练

    到这里为止,其实还是停留在简单学习知识的程度,学会了redis的持久化的原理和操作,但是在企业中,持久化到底是怎么去用得呢? 企业级的数据备份和各种灾难下的数据恢复,是怎么做得呢? 1.企业级的持久化 ...

  3. 西门子 S7-200CN CPU 224CN EEPROM芯片

    拆下来了个 224CN 的EEPROM芯片

  4. class(二)--派生类的继承

    前言 从我之前的一篇笔记对象的继承中, 我们可以知道JS的继承方式依赖原型链,而比较好的继承方式是寄生组合式继承 先来温习下什么是寄生组合式继承 function Rectangle(length, ...

  5. OpenCV HOGDescriptor 参数图解

    防止以后再次掉入坑中,决定还是在写写吧 OpenCV中的HOG特征提取功能使用了HOGDescriptor这个类来进行封装,其中也有现成的行人检测的接口.然而,无论是OpenCV官方说明文档还是各个中 ...

  6. NO11 SSH故障排查思路和netstat命令

    本章知识相关考试:1.企业场景面试题:Linux系统如何优化?2.企业场景面试题:SSH服务连不上,如何排查?记住回答技巧: 1 ping  2 telnet 客户端ssh工具:SecureCRT,x ...

  7. MySQL每日执行

    drop event if exists upload_deadline; DELIMITER $$ create event upload_deadline day starts timestamp ...

  8. Nginx+uwsgi+django部署项目

    nginx把请求转发给uwsgi,然后把uwsgi处理得到的结果返回给浏览器. 安装nginx: yum -y install gcc pcre-devel openssl-devel #安装Ngin ...

  9. mysql union 和union all

    http://www.w3school.com.cn/sql/sql_union.asp

  10. 编译Linux

    下载内核源文件 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/ 生成.config配置文件 make ...