原型

如果你尝试向数组添加一个属性,而且这个属性名“看起来”像是一个数字的话,那么这个新添加的属性将会被作为数组的一个元素项。随之带来的问题是不经意的扩展了数组一项或者若干项。所以说,我们在为数组动态添加属性的时候,应该避免属性名是字符串数字。

JavaScript中的对象有一个特殊的[[Prototype]]内置属性,它其实就是一个对于其他对象的引用。几乎所有的对象在创建时[[Prototype]]属性都会被赋予一个非空的值。不过,[[Prototype]]属性的值可以为空。关键词:所有的对象都具有一个内置的[[Prototype]]属性,并非函数特有。

1.[[Prototype]]属性的作用之——使得[[Get]]查询可以顺藤摸瓜

当我们试图引用对象的属性时会触发[[Get]]操作,对于默认的[[Get]]操作来说,第一步是检查对象本身是否有这个属性,如果有的话那就使用它;但是如果对象里没有这个属性的话,那么会检查对象的[[Prototype]]属性所指向的那个对象有没有这个属性,同理类推接着进行下次寻找。这个过程会持续到找到匹配的属性名或者查找完整的一条[[Prototype]]链。如果是后者的话,那么[[Get]]操作返回的是undefined。举个例子:

var anotherObject = {"a": 2}
var myObject = Object.create(anotherObject)
console.log(myObject)//Object{}
myObject.a//2

我们利用了Object.create()方法将myObject对象的[[Prototype]]关联到了anotherObject,所以说尽管myObject上没有a属性,但是myObject的原型链上有,所以可以顺利的访问到a属性。

使用for...in...遍历对象的时候,也会将该对象原型链上的属性返回:

var obj1 = {"proto1": 1, "proto2": 2}
var obj2 = Object.create(obj1)
obj2.a = "A"
obj2.b = "B"
for(var key in obj2){
  console.log(obj2[key])//A B 1 2
}

2.Object.prototype

某个对象的[[Prototype]]的尽头在哪里?一般来说,所有普通的[[Prototype]]链最终都是指向内置的Object.prototype。所以,在JavaScript中,“普通的”对象都源于这个Object.prototype对象,所以语言规范在Object.prototype中实现了许多通用的功能。

END

你可能感兴趣的:(原型)