原型链 | 青训营笔记

53 阅读2分钟

1.对象的构造函数 在原型对象中有一个属性 constructor可以直接指向构造函数。

function Person() {

    }
    console.log(Person.prototype.constructor)//Person构造函数本身

因为构造函数创建的实例化对象本身没有constructor属性,但是因为连接到了Person函数的原型对象,就可以访问到constructor属性。

console.log(new Person().constructor)//Person构造函数本身 1 因为通过对象的constructor属性可以查询到它的构造函数

原型链的结构 自定义函数,以及Object、String、Number等内置函数,都是由Function函数自身创建的。 每一个构造函数都有一个原型对象,构造函数通过prototype属性指向原型对象,原型对象通过constructor指向构造函数。 由构造函数创造的实例对象,继承自构造函数的原型对象,通过对象的__proto__属性可以直接访问原型对象 构造函数的原型对象,继承自Object的原型对象,而Object的原型对象的__proto__属性为空。 实例化对象的constructor属性可以直接访问原型对象继承的构造函数。 原型链示意图如下

脚下留心 在进行原型操作时,对象.constructor.prototype访问的是该对象当前继承的原型对象的构造函数的原型对象,并不一定是,实例构造函数的原型对象。

实例 function Person() {} function Fun() {} Person.prototype = new Fun(); var p1 = new Person(); p1.constructor === Fun; p1.constructor.prototype === Fun.prototype; p1.proto === Person.prototype

判断1 p1.constructor === Fun;//true

通过构造函数创建的实例对象,他可以直接通过constructor直接访问构造函数的原型对象, 因为创建之前Person.prototype = new Fun();,所以

p1.constructor === Person.prototype.constructor; p1.constructor === (new Fun()).constructor;

等价于实例对象 Fun的constructor属性==Fun

判断2 p1.constructor.prototype === Fun.prototype;//true 上次判断已经指向了构造函数Fun.

判断3 p1.proto === Person.prototype//true 实例对象的__prtoto__属性可以直接访问原型对象。

多学一招 instanceof运算符可以用来检测一个原型链中是否含有某个构造函数的prototype所代表的对象,有返回true ,没有返回false;

	function Person() {};
    function Fun() {};
    var p1 = new Person();
    console.log(p1 instanceof Person); //true
    console.log(p1 instanceof Fun); //false

如果在创建之后更改了Person构造函数的prototype属性为其他对象,那么在使用instanceof检测时,之前创建的对象就不在Person的原型链中了。

function Person() { this.aa = 1 }

    function Fun() {
        this.aa = 2

    }

    var p1 = new Person()
    Person.prototype = new Fun();
    var p2 = new Person();
    console.log(p1 instanceof Person); //false
    console.log(p2 instanceof Person); //true

总结 通过修改原型对象继承的只是原型对象的方法,而构造函数的属性不会变化。