原型链

1.创建对象的方法

// 第一种方式:字面量 var o1 = {name: 'o1'}; var o2 = new Object({name: 'o2'}); //若把Object当做构造函数,可当做第二种方式 //第二种方式:通过构造函数 var F = function(name){this.name=name; } var o3 = new F('o3'); //第三种方式:Object.create, o4.__proto__指向m var m = {name:'o4'}; var o4 = Object.create(m);

2.原型、构造函数、实例、原型链
原型链
文章图片

(1)构造函数:任何函数只要被new使用了,就是构造函数,不被new使用就是普通函数。构造函数也是函数。即上述代码中的F. (2)实例:上述代码中的o1/o2/o3, 都是实例,也是对象。 (3)函数在被声明的时候,js就会自动为它加上prototype属性,就是函数的原型对象。 (4)原型对象如何区分被哪个构造函数引用:原型对象的constructor(构造器)默认指向声明的函数。 (5)实例上的__proto__属性指向原型对象

原型链
文章图片

(6)原型链:从实例对象往上找,构造这个实例相关联的对象,这个关联对象再往上找创造它的上一级原型对象,以此类推,一直到Object.prototype原型对象终止。Object的prototype是整个原型链的顶端。 (7)原型链上的方法和属性是被不同实例对象所共享的.F.prototype.say = function(){console.log('Say Hi'); } var o5 = new F('o5');

【原型链】原型链
文章图片

(8)若在实例本身上找不到某属性或方法,会在该实例的原型对象上找(通过__proto__),若找不到会在该原型对象的上一级原型对象找(通过__proto__),以此类推,直到Object.prototype上若没有,则该实例的某属性或方法没有定义。如果在中间某个原型对象上找到了,则返回该原型对象的某属性或方法,停止向上查找。总结:函数才有prototype,对象是没有prototype的。只有实例对象有__proto__。 普通函数看到有__proto__属性,是因为普通函数其实也是Function构造函数的实例对象。 关系图超级重要!!!

原型链
文章图片

3.instanceof
原理:判断实例对象的__proto属性是否跟构造函数的prototype属性同一个引用,需注意:在同一个原型链上的构造函数,实例对象在调用instanceof时,都是返回true.
A继承B,B继承C,a是A的实例对象,a instanceof B 返回true, a instanceof C 返回true, a instanceof A 返回true,如果判断a是由谁直接生成的实例呢?使用a.__proto__.constructor。

原型链
文章图片

4.new 运算符
原理步骤:
(1) 一个新的空对象被创建,它继承自构造函数F的prototype;
(2) 构造函数F被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new F等同于new F(),只能用在不传递任何参数的情况下。
(3) 如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1所创建的对象。
var new2 = function(func){ var o = Object.create(func.prototype); var k = func.call(o); if(typeof k === 'object'){ return k; }else{ return o; } }

原型链
文章图片

    推荐阅读