JavaScript原型链讲解
1.每个对象都具有一个名为__proto__的属性;
2.每个构造函数(构造函数标准为大写开头,如Function(),Object()等等JS中自带的构造函数,以及自己创建的)都具有一个名为prototype的方法(注意:既然是方法,那么就是一个对象(JS中函数同样是对象),所以prototype同样带有__proto__属性);
3.每个对象的__proto__属性指向自身构造函数的prototype;
基础讲解:
function Fn() {}// Fn为构造函数
var f1 = new Fn();//f1是Fn构造函数创建出来的对象
构造函数的prototype属性值就是对象原型。(Fn.prototype就是对象的原型)
构造函数的prototype属性值的类型就是对象 typeof Fn.prototype===object.
对象原型中的constructor属性指向构造函数 (Fn.prototype.constructor===Fn)
对象的__proto__属性值就是对象的原型。(f1.__proto__就是对象原型)
Fn.prototype===f1.__proto__ 其实它们两个就是同一个对象---对象的原型。
所有Fn.prototype.__proto__===Object.prototype
typeof Object.prototype ===object。
Object.prototype.__proto__===null。
下面按图讲解:
1.标识1
实例对象f1是通过构造函数Foo()的new操作创建的。构造函数Foo()的原型对象是Foo.prototype;实例对象f1通过__proto__属性也指向原型对象Foo.prototype
function Foo(){};var f1 =new Foo; console.log(f1.__proto === Foo.prototype);\\true
实例对象f1本身并没有constructor属性,但它可以继承原型对象Foo.prototype的constructor属性
function Foo(){};var f1 =new Foo; console.log(Foo.prototype.constructor === Foo);//trueconsole.log(f1.constructor === Foo);/true console.log(f1.hasOwnProperty('constructor'));false
2.标识2
函数也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过Function()构造函数的new操作实例化的结果
var obj1=new Function(); console.log(obj1.constructor); console.log(Function);//两个的结果是一样的
如果把函数Foo当成实例对象的话,其原型对象(标识4,5)是Function.prototype;原型对象Function.prototype的constructor属性指向构造函数Function();函数Object的构造函数也是Function(),实例对象Object和Foo本身没有constructor属性,需要继承原型对象Function.prototype的constructor属性。
function Foo(){};var f1 = new Foo; console.log(Foo.__proto__ === Function.prototype);//trueconsole.log(Object.__proto__ === Function.prototype);//true
function Foo(){};var f1 = new Foo; console.log(Function.prototype.constructor === Function);//trueconsole.log(Foo.constructor === Function);//trueconsole.log(Foo.hasOwnProperty('constructor'));//falseconsole.log(Object.constructor === Function);//trueconsole.log(Object.hasOwnProperty('constructor'));//false
所有的函数都可以看成是构造函数Function()的new操作的实例化对象。那么,Function可以看成是调用其自身的new操作的实例化的结果
所以,如果Function作为实例对象,其构造函数是Function,其原型对象是Function.prototype
console.log(Function.__proto__ === Function.prototype);//trueconsole.log(Function.prototype.constructor === Function);//trueconsole.log(Function.prototype === Function.prototype);//true
如果Function.prototype作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是Object()构造函数的new操作的实例化结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()
console.log(Function.prototype.__proto__ === Object.prototype);//true
需要注意的指向是
Function的__proto__指向其构造函数Function的prototype;
Object作为一个构造函数(是一个函数对象!!函数对象!!),所以他的__proto__指向Function.prototype;
Function.prototype的__proto__指向其构造函数Object的prototype;
Object.prototype的__prototype__指向null(尽头);
hasOwnProperty判断一个对象是否有名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员