彻底理解JavaScript中的prototype、__proto__

虽然在JavaScript里一切皆对象,但为了理解原型链系统,我们需要将JavaScript的对象分为对象和函数两大类。在此基础上,JavaScript的原型链逻辑遵从以下通用规则:

  • 对象有__proto__属性,函数有prototype属性;
  • 对象由函数生成;
  • 生成对象时,对象的__proto__属性指向函数的prototype属性。

在没有手动修改__proto__属性的指向时,以上三条便是JavaScript默认原型链指向逻辑。

1、一般情况:

// 创建空对象时,实际上我们是用Object函数来生成对象的:
var o = {}
o.__proto__ === Object.prototype 
// ==> true

// 我们也可以显式的使用Object函数来创建对象:
var o = Object()
o.__proto__ === Object.prototype
// ==> true

// 当我们使用函数来创建自定义的对象时,上面的规则同样适用:
function MyObj(){}
typeof MyObj
// ==> "function"
var mo = new MyObj()
mo.__proto__ === MyObj.prototype
// ==> true     

2、函数对象
既然JavaScript里“一切皆对象”,那函数自然也是对象的一种。对于函数作为对象来说,上面的规则同样适用:

// 函数对象都是由Function函数生成的:
>function fn(){}
>fn.__proto__ === Function.prototype
// ==> true

// Function函数本身作为对象时,生成它的函数是他自身!
>Function.__proto__ === Function.prototype
// ==> true

// Object函数既然是函数,那生成它的函数自然是Function函数咯:
>Object.__proto__ === Function.prototype
// ==> true

来看一个例子:

function Say(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Say('jone', 30);
console.log(person instanceof Say);                                         // ==> true
console.log(person.__proto__ === Say.prototype);                            // ==> true
console.log(person.__proto__.constructor === Say.prototype.constructor);    // ==> true
var obj = {};
console.log(obj.__proto__ == Object.prototype)                              // ==> true
var fn = function() {};
console.log(fn.__proto__ === Function.prototype);                           // ==> true

总结:

js里所有的对象都有__proto__属性(对象,函数),指向构造该对象的构造函数的原型。
只有函数function才具有prototype属性。这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

猜你喜欢

转载自www.cnblogs.com/jone-chen/p/11124580.html