(本文未经许可禁止转载)

           

prototype-vs-proto

以下是我自己总结的规律,有可能不对。阅读请注意

首先万物皆对象,就算声明一个函数类型,这个函数也本质是个对象。

声明体

__proto__返回声明体的前半截的原型对象。
prototype返回声明体的后半截的原型对象。

例如:

function Foo(){};

这代码声明了一个函数对象Foo

因为前半截声明为function,后半截为Foo

所以:

Foo.__proto__返回Function.prototype

Foo.prototype返回Foo.prototype(由环境设置的对象)

实例化

如果用new实例化Foo的话

a = new Foo();

a在这里接收到一个对象后,a的类型就变为Foo object

所以a.__proto__将返回Foo.prototype
所以a.prototype将返回a.prototype(一般为undefined)

循环引用

a = {};
b = {};

a.prototype=b; // OK
b.prototype=a; // OK

a.__proto__=b; // OK
b.__proto__=a; // Error: Cyclic __proto__ value

查值

a = {};
b = {name:'MiLai'};

a.prototype=b;
console.log(a.name); // undefined
a = {};
b = {name:'MiLai'};

a.__proto__=b;
console.log(a.name); // MiLai

类的实现

function a(){this.data = 3;}; // a.prototype 将自动生成
a.prototype.say = function(){console.log("Hi");};

b = new a();
/*
b = {};
b.__proto__ = a.prototype;
this = b;
b.__proto__.constructor();
*/
b.say(); // Hi
console.log(b.data); // 3

c = new a();
c.say = function(){console.log("Hello")};
c.say(); // Hello
console.log(c.data); // 3

c.data=4;
console.log(c.data); // 4
console.log(b.data); // 3

a.prototype.data = 5;
console.log(c.data); // 4
console.log(b.data); // 3

b.data = undefined;
console.log(c.data); // 4
console.log(b.data); // undefined
console.log(b.hasOwnProperty('data')); // true

delete b.data;
console.log(c.data); // 4
console.log(b.data); // 5
console.log(b.hasOwnProperty('data')); // false

注意:js内部调用Object.prototype.hasOwnProperty(key)来判断是否需要递归原型链

       

(本文未经许可禁止转载)

   

发表评论