JavaScript 不包含传统的类继承模型,而是使用?prototypal?原型模型。 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。 由于 JavaScript 是唯一一个被广泛使用的基于原型继承的语言,所以理解两种继承模式的差异是需要一定时间的。 第一个不同之处在于 JavaScript 使用原型链的继承方式。 注意:?简单的使用? * 注意:?不要使用? 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。 到查找到达原型链的顶部 - 也就是? 当原型属性用来创建原型链时,可以把任何类型的值赋给它(prototype)。 而将对象赋值给 prototype,正如上面的例子所示,将会动态的创建原型链。 如果一个属性在原型链的上端,则对于查找时间将带来不利影响。特别的,试图获取一个不存在的属性将会遍历整个原型链。 并且,当使用? 一个错误特性被经常使用,那就是扩展? 这种技术被称之为?monkey patching?并且会破坏封装。虽然它被广泛的应用到一些 JavaScript 类库中比如?Prototype, 扩展内置类型的唯一理由是为了和新的 JavaScript 保持一致,比如? 译者注:这是编程领域常用的一种方式,称之为?Backport,也就是将新的补丁添加到老版本中。 在写复杂的 JavaScript 应用之前,充分理解原型链继承的工作方式是每个 JavaScript 程序员必修的功课。原型
实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。
(It is for example fairly trivial to build a classic model on top of it, while the
other way around is a far more difficult task.)
Bar.prototype = Foo.prototype
?将会导致两个对象共享相同的原型。
因此,改变任意一个对象的原型都会影响到另一个对象的原型,在大多数情况下这不是希望的结果。function Foo() {
this.value = 42;
}
Foo.prototype = {
method: function() {}
};
function Bar() {}
// 设置Bar的prototype属性为Foo的实例对象
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';
// 修正Bar.prototype.constructor为Bar本身
Bar.prototype.constructor = Bar;
var test = new Bar() // 创建Bar的一个新实例
// 原型链
test [Bar的实例]
Bar.prototype [Foo的实例]
{ foo: 'Hello World' }
Foo.prototype
{method: ...};
Object.prototype
{toString: ... /* etc. */};
上面的例子中,test
?对象从?Bar.prototype
?和?Foo.prototype
?继承下来;因此,
它能访问?Foo
?的原型方法?method
。它也同时能够访问那一个作为它原型的?Foo
?实例
的属性?value
。需要注意的是?new Bar()
?不会创造出一个新的?Foo
?实例,而是
重新使用设定为它的原型的实例;也就是说,所有的?Bar
?实例都将会有同样的?value
?属性。
Bar.prototype = Foo
,因为这不会执行?Foo
?的原型,而是指向函数?Foo
。
因此原型链将会回溯到?Function.prototype
?而不是?Foo.prototype
,因此?method
?将不会在 Bar 的原型链上。属性查找
Object.prototype
?- 但是仍然没有找到指定的属性,就会返回?undefined。原型属性
然而将原子类型赋给 prototype 的操作将会被忽略。function Foo() {}
Foo.prototype = 1; // 无效
性能
for in
?循环遍历对象的属性时,原型链上的所有属性都将被访问。扩展内置类型的原型
Object.prototype
?或者其他内置类型的原型对象。
但是我仍然不认为为内置类型添加一些非标准的函数是个好主意。Array.forEach
。
总结
要提防原型链过长带来的性能问题,并知道如何通过缩短原型链来提高性能。
更进一步,绝对不要扩展内置类型的原型,除非是为了和新的 JavaScript 引擎兼容。
详细解决方案
JavaScript Garden - 原形
热度:446 发布时间:2012-10-07 17:28:51.0
相关解决方案
- javascript ie6兼容的有关问题
- javascript window open在ie中设立不起作用,求解决
- javascript 字符串拼接效率有关问题
- JavaScript 自动生成图片并合并有关问题
- 不走"<script type='text/javascript'>"标签咋回事
- <script type="javascript/text">的有关问题
- 用servlet+jsp+javascript+jdbc做个简单的办公自动化系统流程,该如何解决
- 怎么打开 javascript:SetData(2010,5,10)
- javaScript = == ===区别,该怎么解决
- javascript 怎么验证name=xx.xx的radio表单
- form action 和 javascript 的提交問題解决方法
- javascript,该怎么处理
- javascript,该如何处理
- javascript 选中文字 但是保存样式 标签
- 新人求问,J2EE方向,html,css,javascript,vml要学到什么程度?解决思路
- javascript 请求servlet兑现将函数中定义的变量作为参数
- javascript 不懂,该如何处理
- javascript 不懂解决方法
- JavaScript 大局函数求实例,高分求
- javaScript 里面 如何知道Object 对象的长度
- javascript 函数调用有什么有关问题,请
- javascript 中文本框中数字如何比较
- javascript IE通过,火狐,google浏览器不过解决思路
- javascript rsa加密/java使用Cipher.getInstance("RSA/ECB/PKCS1Padding")解密,该如何处理
- IE javascript start()函数解决方案
- 关于RTMP 播放器(DELPHI C# FLASH JAVASCRIPT)解决思路
- Chrome Javascript Click 事件,该如何解决
- javascript 实出_blank跳转到新标签页有关问题
- 分享上Google Maps Javascript API v3
- javascript 绑定服务器控件 事件,该如何解决