Javascript原型链

原型链属性

1
var obj = { name: 'obj' }

obj 有两个属性:一个是添加的 name 属性,一个是自带的_ _proto__属性,指向 window.Object.prototype。如下图所示。

示意图

window.Object.prototype

这样你在调用 obj.toString() 的时候,obj 本身没有 toString,就去 obj._ _ proro__ 上面去找 toString。所以你调用 obj.toString 的时候,实际上调用的是 window.Object.prototype.toString

那么 window.Object.prototype.toString 是怎么获取 obj 的内容的呢?

那是因为 obj.toString() 等价于 obj.toString.call(obj)

同时 obj.toString.call(obj) 等价于 window.Object.prototype.toString.call(obj)这句话把 obj 传给 toString 了

array.push

这样你在调用 arr.push 的时候,arr 自身没有 push 属性,就去 arr._ _ proto__ 上找 push 因此 arr.push 实际上是 window.Array.prototype.push

arr.push(1) 等价与 arr.push.call(arr,1)

arr.push.call(arr,1) 等价于 window.Array.prototype.push.call(arr, 1)

共享原型链

1
var obj2 = { name: 'obj2' }

如果我们改写 obj2._ _ proto__.toString,那么 obj.toString 其实也会变!

差异化

如果我们想让 obj.toString 和 obj2.toString 的行为不同怎么做呢?

1
obj.toString = function(){ return '新的 toString 方法' }

总结

“读”属性时会沿着原型链搜索。

“新增”属性时不会去看原型链

prototype 指向一块内存,这个内存里面有共用属性,_ _ proto__ 指向同一块内存

prototype 和 _ _ proto_ _ 的不同点在于: prototype 是构造函数的属性,而 *_ _ proto_ _ 是对象的属性

难点在于……构造函数也是对象!

如果没有 prototype,那么共用属性就没有立足之地,如果没有 _ _ proto_ _,那么一个对象就不知道自己的共用属性有哪些。

1. prototype 是构造函数的一个属性。

2. _ _ proto_ _是实例的属性,一般意义上的【实例的原型】。

3. 开发人员对构造函数属性 prototype 的操作,最终会反应到该构造函数的实例上。

参考 1

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2018-2020 Jee
  • Visitors: | Views:

如果您觉得此文章帮助到了您,请作者喝杯咖啡吧~

支付宝
微信