三个关键词
construct: 对象的构造函数属性(指向一个方法)
prototype: 构造函数的原型属性(指向一个对象)
_proto_ ([[prototype]]): 对象的原型指向(不可枚举)(指向一个对象)
原型链图解
图示说明:
(1)在实际浏览器输出中对象会有一个[[Prototyp]]属性,这个属性指向的是对象的原型。应该就是_proto_的另一种写法(如果有大佬知道的可以在评论去留言告知)。
(2)_pro_指示方向就是对象在原型链上查询的方向,实际中_pro_是不可枚举的。对于其内部实现机制也不太了解,所以它仅仅只是告诉我们作用域的指示方向而已。
(3)如果要推断某对象是否继承某对象,建议先找寻对象(constructor)的构造函数,然后再确定构造函数的原
(4)对象一旦实例化后其原型链接已经创立,就无法通过constructor与prototype来修改原型链了,但可以通过其修改原型对象的属性。
(5)非构造函数新建对象时,所有的新建对象原型都指向Object.prototyp,新建数组时其所有数组原型都指向Array.prototype。
var a={}; var b=new Object(); Object.prototype.test="test"; console.log(a.test); console.log(b.test);//"test","test" var c=[];console.log(c.test); //test 这里更验证了Array.prototype的原型指向Object.prototype Array.prototype.ArrTest="arrPro"; console.log(c.ArrTest); console.log(a.ArrTest);//"arrPro" , undefined
(6)在新建函数时,因为是函数,为它的原型属性(prototype)创建一个新对象,该对象继承ObJect.prototype。
bject.prototype.test="test"; var a=function(){}; var b=new a(); console.log(b.test);//"test"
同时因为函数也是对象,因此它的原型被指向Function.Prototype,其构造函数指向Function。这样保证使用函数时能获取到Function.prototype的内置方法。
(7)通常继承是在创建构造函数后,通过使构造函数的原型属性(prototype)指向另一个对象。而另一个原型对象的构造函数可能没有或指向其他函数。这样容易混乱
所以需要F.prototype.constructor=F;
2.2 原型链中常用的一些方法
instanceof:对象 instanceof 构造函数
判断构造函数的prototype属性对象是否存在于对象的原型链上。
返回值:Boolean true/false;
let arr=[]; console.log(arr instanceof Array); //true console.log(arr instanceof Object);//true console.log(arr instanceof Function); //false
hasOwnProperty:obj.hasOwnProperty("a");
检查obj中读取的a属性是否是自身属性。
返回值:true自身定义的属性,false 来自原型链(如果原型链和自身属性名相同,则会读取自身属性值,所以返回true)
in : 属性 in 对象
判断某对象是否有某属性。包括原型链上继承的属性
let foo=function(){}; foo.prototype.name="test"; let obj=new foo(); console.log(obj.hasOwnProperty("name")); //false console.log("name" in obj);//true obj.age=28; obj.name='list' console.log(obj.hasOwnProperty("name"));//true console.log(obj.hasOwnProperty("age"));//true console.log("test" in obj);//false
Object.getPrototypeOf(): Object.getPrototypeOf(obj);
返回指定对象的原型(内部[[Prototype]]或_proto_)
console.log(Object.getPrototypeOf(Object.prototype));//null console.log(Object.getPrototypeOf(Function.prototype)===Object.prototype);//true
isPrototypeOf: obj.isPrototypeOf(objProto)
一个对象(objProto)是否存在于另一个对象(obj)的原型链上
let objProto={};
let foo=function(){};
foo.prototype=objProto;
foo.prototype.constructor = foo;
let obj=new foo();
console.log(objProto.isPrototypeOf(obj)); //true
let objProto={}; let foo=function(){}; foo.prototype=objProto; foo.prototype.constructor = foo; let obj=new foo(); console.log(objProto.isPrototypeOf(obj)); //true