JavaScript探秘:原型链 Prototype chain
2011-05-06 00:00
821 查看
原型对象也是普通的对象,并且也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链(prototype chain)。
A prototype chain is a finite chain of objects which is used to implemented inheritance and shared properties.
原型链是一个由对象组成的有限对象链由于实现继承和共享属性。
想象一个这种情况,2个对象,大部分内容都一样,只有一小部分不一样,很明显,在一个好的设计模式中,我们会需要重用那部分相同的,而不是在每个对象中重复定义那些相同的方法或者属性。在基于类[class-based]的系统中,这些重用部分被称为类的继承 – 相同的部分放入class A,然后class B和class C从A继承,并且可以声明拥有各自的独特的东西。
ECMAScript没有类的概念。但是,重用[reuse]这个理念没什么不同(某些方面,甚至比class-更加灵活),可以由prototype chain原型链来实现。这种继承被称为delegation based inheritance-基于继承的委托,或者更通俗一些,叫做原型继承。
类似于类”A”,”B”,”C”,在ECMAScript中尼创建对象类”a”,”b”,”c”,相应地, 对象“a” 拥有对象“b”和”c”的共同部分。同时对象“b”和”c”只包含它们自己的附加属性或方法。
这样看上去是不是很简单啦。b和c可以使用a中定义的calculate方法,这就是有原型链来[prototype chain]实现的。
原理很简单:如果在对象b中找不到calculate方法(也就是对象b中没有这个calculate属性), 那么就会沿着原型链开始找。如果这个calculate方法在b的prototype中没有找到,那么就会沿着原型链找到a的prototype,一直遍历完整个原型链。记住,一旦找到,就返回第一个找到的属性或者方法。因此,第一个找到的属性成为继承属性。如果遍历完整个原型链,仍然没有找到,那么就会返回undefined。
注意一点,this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。例如,以上的例子,this.y是从b和c中获取的,而不是a。当然,你也发现了this.x是从a取的,因为是通过原型链机制找到的。
如果一个对象的prototype没有显示的声明过或定义过,那么__prototype__的默认值就是object.prototype, 而object.prototype也会有一个__prototype__, 这个就是原型链的终点了,被设置为null。
下面的图示就是表示了上述a,b,c的继承关系:
原型链
原型链通常将会在这样的情况下使用:对象拥有 相同或相似的状态结构(same or similar state structure) (即相同的属性集合)与 不同的状态值(different state values)。在这种情况下,我们可以使用 构造函数(Constructor) 在 特定模式(specified pattern) 下创建对象。
我们应该如何去了解JavaScript引擎的工作原理
JavaScript探秘:编写可维护的代码的重要性
JavaScript探秘:谨慎使用全局变量
JavaScript探秘:var预解析与副作用
JavaScript探秘:for循环(for Loops)
JavaScript探秘:for-in循环(for-in Loops)
JavaScript探秘:Prototypes强大过头了
JavaScript探秘:eval()是“魔鬼”
JavaScript探秘:用parseInt()进行数值转换
JavaScript探秘:基本编码规范
JavaScript探秘:函数声明与函数表达式
JavaScript探秘:命名函数表达式
JavaScript探秘:调试器中的函数名
JavaScript探秘:JScript的Bug
JavaScript探秘:JScript的内存管理
JavaScript探秘:SpiderMonkey的怪癖
JavaScript探秘:命名函数表达式替代方案
JavaScript探秘:对象Object
JavaScript探秘:原型链 Prototype chain
JavaScript探秘:构造函数 Constructor
JavaScript探秘:可执行的上下文堆栈
执行上下文其一:变量对象与活动对象
执行上下文其二:作用域链 Scope Chains
执行上下文其三:闭包 Closures
执行上下文其四:This指针
JavaScript探秘:强大的原型和原型链
JavaScript函数其一:函数声明
JavaScript函数其二:函数表达式
JavaScript函数其三:分组中的函数表达式
JavaScript函数其四:函数构造器
JavaScript变量对象其一:VO的声明
JavaScript变量对象其二:VO在不同的执行上下文中
JavaScript变量对象其三:执行上下文的两个阶段
JavaScript变量对象其四:关于变量
JavaScript变量对象其五:__parent__ 属性
JavaScript作用域链其一:作用域链定义
JavaScript作用域链其二:函数的生命周期
JavaScript作用域链其三:作用域链特征
JavaScript闭包其一:闭包概论
JavaScript闭包其二:闭包的实现
JavaScript闭包其三:闭包的用法
A prototype chain is a finite chain of objects which is used to implemented inheritance and shared properties.
原型链是一个由对象组成的有限对象链由于实现继承和共享属性。
想象一个这种情况,2个对象,大部分内容都一样,只有一小部分不一样,很明显,在一个好的设计模式中,我们会需要重用那部分相同的,而不是在每个对象中重复定义那些相同的方法或者属性。在基于类[class-based]的系统中,这些重用部分被称为类的继承 – 相同的部分放入class A,然后class B和class C从A继承,并且可以声明拥有各自的独特的东西。
ECMAScript没有类的概念。但是,重用[reuse]这个理念没什么不同(某些方面,甚至比class-更加灵活),可以由prototype chain原型链来实现。这种继承被称为delegation based inheritance-基于继承的委托,或者更通俗一些,叫做原型继承。
类似于类”A”,”B”,”C”,在ECMAScript中尼创建对象类”a”,”b”,”c”,相应地, 对象“a” 拥有对象“b”和”c”的共同部分。同时对象“b”和”c”只包含它们自己的附加属性或方法。
var a = { x: 10, calculate: function (z) { return this.x + this.y + z } }; var b = { y: 20, __proto__: a }; var c = { y: 30, __proto__: a }; // 调用继承过来的方法 b.calculate(30); // 60 c.calculate(40); // 80
这样看上去是不是很简单啦。b和c可以使用a中定义的calculate方法,这就是有原型链来[prototype chain]实现的。
原理很简单:如果在对象b中找不到calculate方法(也就是对象b中没有这个calculate属性), 那么就会沿着原型链开始找。如果这个calculate方法在b的prototype中没有找到,那么就会沿着原型链找到a的prototype,一直遍历完整个原型链。记住,一旦找到,就返回第一个找到的属性或者方法。因此,第一个找到的属性成为继承属性。如果遍历完整个原型链,仍然没有找到,那么就会返回undefined。
注意一点,this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。例如,以上的例子,this.y是从b和c中获取的,而不是a。当然,你也发现了this.x是从a取的,因为是通过原型链机制找到的。
如果一个对象的prototype没有显示的声明过或定义过,那么__prototype__的默认值就是object.prototype, 而object.prototype也会有一个__prototype__, 这个就是原型链的终点了,被设置为null。
下面的图示就是表示了上述a,b,c的继承关系:
原型链
原型链通常将会在这样的情况下使用:对象拥有 相同或相似的状态结构(same or similar state structure) (即相同的属性集合)与 不同的状态值(different state values)。在这种情况下,我们可以使用 构造函数(Constructor) 在 特定模式(specified pattern) 下创建对象。
延伸阅读
此文章所在专题列表如下:我们应该如何去了解JavaScript引擎的工作原理
JavaScript探秘:编写可维护的代码的重要性
JavaScript探秘:谨慎使用全局变量
JavaScript探秘:var预解析与副作用
JavaScript探秘:for循环(for Loops)
JavaScript探秘:for-in循环(for-in Loops)
JavaScript探秘:Prototypes强大过头了
JavaScript探秘:eval()是“魔鬼”
JavaScript探秘:用parseInt()进行数值转换
JavaScript探秘:基本编码规范
JavaScript探秘:函数声明与函数表达式
JavaScript探秘:命名函数表达式
JavaScript探秘:调试器中的函数名
JavaScript探秘:JScript的Bug
JavaScript探秘:JScript的内存管理
JavaScript探秘:SpiderMonkey的怪癖
JavaScript探秘:命名函数表达式替代方案
JavaScript探秘:对象Object
JavaScript探秘:原型链 Prototype chain
JavaScript探秘:构造函数 Constructor
JavaScript探秘:可执行的上下文堆栈
执行上下文其一:变量对象与活动对象
执行上下文其二:作用域链 Scope Chains
执行上下文其三:闭包 Closures
执行上下文其四:This指针
JavaScript探秘:强大的原型和原型链
JavaScript函数其一:函数声明
JavaScript函数其二:函数表达式
JavaScript函数其三:分组中的函数表达式
JavaScript函数其四:函数构造器
JavaScript变量对象其一:VO的声明
JavaScript变量对象其二:VO在不同的执行上下文中
JavaScript变量对象其三:执行上下文的两个阶段
JavaScript变量对象其四:关于变量
JavaScript变量对象其五:__parent__ 属性
JavaScript作用域链其一:作用域链定义
JavaScript作用域链其二:函数的生命周期
JavaScript作用域链其三:作用域链特征
JavaScript闭包其一:闭包概论
JavaScript闭包其二:闭包的实现
JavaScript闭包其三:闭包的用法
相关文章推荐
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript探秘:强大的原型和原型链
- JavaScript原型OOP——你上车了吗?
- 深入理解javascript原型和闭包(4)——隐式原型
- 6、JavaScript高级之继承一(原型链)
- 深入理解javascript之原型
- Javascript---原型prototype
- JavaScript原型prototype
- 基于原型的JavaScript面向对象
- javascript中的类方法、构造方法、原型方法的对比
- 探秘JavaScript中的六个字符
- JavaScript原型深入解析
- 简单分析javascript面向对象与原型
- JavaScript--深入理解原型与闭包