-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
原型
有时候,当我们访问对象上不存在的属性或者方法时,依然可以得到结果,这是因为这些属性或方法存在于一个共享对象中,这个对象就是原型。它位于构造函数的prototype
属性上,实例对象通过私有属性__proto__
指向原型对象,所以,在实例对象中找不到的属性或者方法引擎会继续顺着__proto__
找到原型对象。原型对象prototype
通过属性constructor
与构造函数产生联系,我们可以通过该属性来判断实例的类型。大多数对象都有原型对象(通过Object.create(null)
创建的对象没有原型),包括原型对象本身,原型对象的存在,帮我们解决了实例对象共享的问题。
var obj = {
foo: 5
}
Object.prototype.bar = 10
console.log(obj.foo) // 5
console.log(obj.bar ) // 10
/********************************************/
console.log(obj.__proto__ === Object.prototype) // true
console.log(Object.prototype.constructor === Object) // true
/********************************************/
var npobj = Object.create(null)
console.log(npobj.__proto__) // undefined
原型链
通过原型我们知道,实例对象存在一个共享的原型,实例中没有的属性或者方法可以在原型中访问到,如果我们去访问一个连原型上也没有的属性或方法呢?是否意味着就结束查找并返回undefined
?答案是否定的。
原型对象并不意味着结束,多数对象都有原型,原型对象也不例外。根据js引擎的查找机制,它会顺着原型对象的原型(o.__proto__.__proto__
)继续查找,终点是哪儿?因为JavaScript中的对象都继承至构造函数Object
,所以,终点就是Object
的原型Object.prototype
。
综上,我们把这种通过__proto__
连接起来的一层一层向上查找的机制叫原型链。JavaScript中的继承主要靠原型链实现,至于继承的实现我们在后面讲解。
var arr = [2, 3]
arr.push(5)
console.log(arr) // [2, 3, 5]
console.log(arr.push === Array.prototype.push) // true
console.log(arr.valueOf()) // [2, 3, 5]
console.log(arr.valueOf === Array.prototype.valueOf) // false
console.log(arr.valueOf === Object.prototype.valueOf) // true
console.log(Array.prototype.__proto__ === Object.prototype) // true 数组继承至Object