@(JS技巧)[原型]
JavaScript原型学习笔记
什么是原型?
- 每当你去定义一个prototype的时候,相当于把该实例的
__proto__
指向一个结构体,那么这个被指向结构体就称为该实例的原型; - 原型是一个对象,其他对象可以通过它实现属性继承;
- 任何一个对象都可以成为原型;
- 所有的对象在默认的情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型(只有一种例外,默认的对象原型在原型链的顶端);
- 一个对象的真正原型是被对象内部的
[[Prototype]]
属性(property
)所持有。ECMA引入了标准对象原型访问器Object.getPrototype(object)
,到目前为止只有Firefox和chrome实现了此访问器。除了IE,其他的浏览器支持非标准的访问器__proto__
,如果这两者都不起作用的,我们需要从对象的构造函数中找到的它原型属性。
__proto__
的指向
- 当不指定
__proto__
的时候,foo也会预留一个这样的属性, - 如果有明确的指向,那么这个链表就链起来啦;
-
__proto__
默认也有指向,它指向的是最高级的object.prototype
,而object.prototype
的__proto__
为空。
很明显,下图中b和c共享a的属性和方法,同时又有自己的私有属性。
Paste_Image.pngvar a = {
x: 10,
calculate: function (z) {
return this.x + this.y + z
}
};
var b = {
y: 20,
__proto__: a
};
var c = {
y: 30,
__proto__: a
};
// call the inherited method
b.calculate(30); // 60
原型的作用
- 我们想要继承一个已经存在的对象的功能时,原型很有用;
- 原型真正魅力体现在多个实例共用一个通用原型的时候。原型对象(注:也就是某个对象的原型所引用的对象)的属性一旦定义,就可以被多个引用它的实例所继承(注:即这些实例对象的原型所指向的就是这个原型对象),这种操作在性能和维护方面其意义是不言自明的;
- JS的原型提供了极强的灵活性;
prototype
每个函数都有一个属性叫做prototype
。
这个prototype
的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor
的属性,指向这个函数本身.
__proto__
- “
__proto__
”,这个属性引用了创建这个对象的函数的prototype。即:fn.__proto__ === Fn.prototype
这里的"__proto__
"成为“隐式原型” -
obj.__proto__
和Object.prototype
的属性一样! - 每个对象都有一个
__proto__
属性,指向创建该对象的函数的prototype -
Object.prototype
(位于最顶端)确实一个特例——它的__proto__
指向的是null。
constructor
- 当定义一个prototype的时候,会构造一个原形对象,这个原型对象存储于构造这个prototype的函数的原形方法之中.;
- 构造函数提供了一种方便的跨浏览器机制,这种机制允许在创建实例时为实例提供一个通用的原型;
- 函数A的原型属性(
prototype property
)是一个对象,当这个函数被用作构造函数来创建实例时,该函数的原型属性将被作为原型赋值给所有对象实例(注:即所有实例的原型引用的是函数的原型属性); - constructor是原型属性中的一个指向其构造函数;
//prototype是本函数的一个属性
//b.constructor指向其构造函数
b.prototype==b.constructor.prototype //fasle
//__proto__指向构造函数的原型
b.prototype==b.__proto__ //false
b.__proto__==b.constructor.prototype //true
Paste_Image.png
instance of 和原型有什么关系
- 如果a的原型属于A的原型链,表达式 a instance of A 值为true
- Instanceof的判断队则是:沿着A的
__proto__
这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false。 - instanceof表示的就是一种继承关系,或者原型链的结构
原型链与继承的关系
- 访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着
__proto__
这条链向上找,这就是原型链。 - 由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。
hasOwnProperty
- 区分一个属性到底是基本的还是从原型中找到的;
- 本方法继承自Object.prototype;
参考文献
JavaScript探秘:强大的原型和原型链
js原型链原理看图说明
理解JavaScript原型
深入理解javascript原型和闭包(完结)(推荐阅读)
网友评论