原型链

it2022-05-08  11

创建对象的几种方法:

  1. 字面量方法

    var o1 = {name:'o1'};

  2. new Object():

    var o2 = new Object({name:'o2'})

  3. 构造函数:

    var M = function(name){this.name = name};

    var o3 = new M('o3');

  4. Object.create():

    var f = {name: 'o4'};

    var o4 = Object.create(f);

原型、实例、构造函数的关系?什么是原型链?

  通过代码来解释:

var M = function (name) { this.name = name; }; var o1 = new M('test'); console.log(M.prototype === o1.__proto__);//true console.log(M.prototype.constructor === M);//true

  1.实例是通过new 一个构造函数生成的,即代码中 o1就是实例,M就是构造函数。

  2.构造函数的prototype属性指向的是原型(或者说原型对象)。即代码中 M.prototype === o1.__proto__

  3. 实例的__proto__属性指向的也是原型(或者说原型对象)。即 代码中 M.prototype === o1.__proto__

  4. 原型(或者说原型对象)对象的constructor指向的是构造函数。即代码中 M.prototype.constructor === M

  5.原型链:简单理解就是 原型(原型对象)组成的链,一直通过__proto__属性向上找,直到找到Object的原型时结束。

    以上代码为例:

      1)o1.__proto__  ===  M.prototype;

      2)同样,M.prototype 也有__proto__属性,M.prototype.__ptoto__ === Object.prototype(或者o1.__proto__.__proto__ === Object.prototype)

      3)Object.prototype也有__proto__属性,但比较特殊,为null

    我们把__proto__串起来,直到Object.prototype.__proto__为null为止的链叫做原型链

  如下图所示:

 

 

instanceof 和 constructor

  检测某个对象是不是另一个对象的实例可以用constructor 或者instanceof。

  1. instanceof的原理是:判断实例对象的__proto__和生成该实例的构造函数的prototype是不是引用的同一个地址(或者说是不是相等),如果是返回ture;如果是原型链上向上找的构造函数同样返回true。

  通过代码来解释:    

var M = function (name) { this.name = name; }; var o1 = new M('test'); console.log(o1 instanceof M) //true console.log(o1 instanceof Object) //true

 

    因为o1.__proto__ === M.prototype 所以 o1 instanceof M 返回为true;

    因为 M.prototype.__proto__ === Object.prototype ,即Object是原型链上的构造函数,所以返回为true.

  2. constructor是:判断实例是由哪个构造函数生成的。

  通过代码来解释:

var M = function (name) { this.name = name; }; var o1 = new M('test'); console.log(o1.__proto__.constructor === M) //true console.log(o1.__proto__.constructor === Object) //false

 

 

new 运算符的原理

  当我们new一个实例对象时,JS执行时在内部做了很多工作,下面用伪代码模拟其工作流程:

new Foo('name') => { var obj = {}; //创建一个空对象 obj.__proto__ = Foo.prototype; //把obj的__proto__指向构造函数的原型对象(Foo.prototype),此时建立了obj的原型链 obj->Foo.prototype -> Object.prototype   var result = Foo.call(obj,'name');//改变this指向   return typeof result === 'object'? result : obj //判断result类型是不是对象,是返回result,不是返回obj }

 

     1)创建一个空对象obj,该对象obj继承构造函数的原型(Foo.prototype)

    2) 将这个空对象的__proto__指向构造函数Foo的原型对象

    3)构造函数Foo被执行,在执行的时候,相应的参数会被传入,同时上下文(this)会被替换成obj

    4) 考察第三步的返回值result,如果无返回值或者返回一个非对象的值,则将obj作为新对象返回;否则将result作为新对象返回

转载于:https://www.cnblogs.com/yangkangkang/p/8710683.html


最新回复(0)