最近地铁上重读了《Javascript语言精粹和编程实践》,又有了新的理解。
原型继承
面向对象的语言有三个特性,即封装性、继承和多态。一般来说,三个特性都满足,即称为“面向对象语言”。
“对象系统”的继承特性有三种实现方案,基于类(class-based)、基于原型(prototype-based)和基于元类(metaclass-based)。Javascript采用了基于原型继承实现对象系统。采用“构造器(constructor)”的机制实现类的功用。
在JavaScript中,函数创建之后都会有一个prototype属性,这个属性指向函数的原型对象,同时原型对象的 constructor属性又指向构造函数本身。
即:
function T(){
//构造函数
}
T.prototype === 原型对象
T = T.prototype.constructor
在JavaScript语言和对象系统的实现中,对象(Object)并没有原型,而构造器有原型,属性"<构造器>.prototype"指向原型。对象只有“构造自某个原型”,不存在“拥有某个原型”。
原型也是对象,即原型是对象的一个实例。原型的含义是指:如果构造器有一个原型对象A,那么由该构造器创建的实例(instance)都复制自A。所以实例继承了A的所有属性、方法和其他性质。
原型也是对象实例
假设有一个构造器T , T的原型对象为M,T是一个函数(Function),M是一个对象(OBJECT)。
即:T.prototype = M
原型对象M中含有一个constructor 属性指向构造器本身。
即 M.constructor = T = T.prototype.constructor
而同时原型对象 M 也是 对象(OBJECT)的一个实例。而对象(OBJECT)同时也是构造器。那么Object 的原型对象是什么呢?实现一下我们可以得到:
Object.prototype // {} 空的对象
因为Object也是构造器,即Object也是函数,所以
Object.constructor // Function
而对Function来说,Function也是一个函数,同时也是一个构造器,function的原型对象是
Function.prototype
我从MDN上找到一段描述:
The
**Function.prototype**
property represents theFunction
prototype object.
Function
objects inherit fromFunction.prototype
.Function.prototype
cannot be modified.
Function.prototype属性存储了Function的原型对象。Function对象继承自Function.prototype属性,因此,Function.prototype不能被修改。
那么 ,Function的原型对象Function.prototype 同时也是Object的一个实例。
原型链
在JavaScript,每个函数都有一个prototype属性,指向构造器的原型,而在对象上,都有一个隐式的__proto__属性,指向原型。
即:__proto__ === constructor.prototype
那么构造器 对象的(Object)的原型对象 Object.prototype 为 空的对象。
所以Oject.prototype是所有对象的根源 {}
而Function.prototype则构造自 Object.prototype上。
Function.prototype.__proto__ = Object.prototype
而空的对象 {} (Object.prototype) 来自 null
即 Object.prototype.__proto__ === null //true
属性查找
当查找一个对象的属性时,Javascript会向上遍历原型链,直到找到给定名称的属性为止,如果查找到原型链顶端——Object.prototype——仍然没有找到指定属性,那么就会返回undefined。
对象的属性在查找时,先查找自身的属性,然后查找原型,再往上到Object的原型上。
hasOwnProperty函数:
hasOwnProperty是Object.prototype的一个方法,它可是个好东西,他能判断一个对象是否包含自定义属性而不是原型链上的属性,因为hasOwnProperty 是 JavaScript 中唯一一个处理属性但是不查找原型链的函数。
网友评论