当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

JavaScript 之原型与周边 - rccoder的segmentfault

作者:小梦 来源: 网络 时间: 2024-06-18 阅读:

简介

如果之间学习过cppjava 之类的语言,都会知道他们是可以基于类 class 进行继承的, 在JavaScript 中,并没有类继承这个概念,要实现JavaScript 中的继承,需要原型来帮助。

比如在下面的这段代码中:

function Foo () {  this.value = 1;};Foo.prototype = {  method: function () {};};//设置Bar的原型为Foo()的实例Bar.prototype = new Foo();Bar.prototype.foo = 'Hello World';//修正Bar的constructorBar.prototype.constructor = Bar;//创建一个Bar的实例var test = new Bar();

在这段代码中,就一直维护着一个原型链,抽象化的理解起来可能是这样的:

test [Bar的实例]     Bar.prototype [Foo的实例]         {foo: 'Hello World!'}         Foo.prototype{method: function(){}}Object.prototype    {...}

很好去理解,test 是从Bar.prototypeFoo.prototype 中继承下来的,所以他能够访问Foo 实例属性中的value

需要注意的是,在 new Bar 操作中,并不会重新创建一个Foo 的实例,而是会重复的使用在他的原型上的那个实例。

除此之外,原型是共享的,如果我们有Foo.prototype = Bar.prototype 的写法,改变这两个对象任何一个的原型都会影响另外一个,这在大多的情况下是不可取的。

当对象查找一个属性的时候,他会沿着原型链一直往上追踪,直到直到为之。当然 Object.prototypr 就是这个链的最后一层了,如果还是没找到,就会返回undefined

hasOwnProperty

在性能方面,原则上应该尽量避免原型链太长。正如用for ... in ... 去遍历的时候,他会去遍历整个原型链,这往往在比较高的性能要求或者普通的遍历中是不可取的。

为了去判断一个对象包含的属性是他本身就有的还是在原型链上的,需要使用继承在Object prototype 上的hasOwnProperty 方法。

比如在下面的例子中

Oboject.prototype.bar = 1;var foo = {  value: 2;};foo.var          //通过原型链继承自Object,输出1'bar' in foo;    //通过整个原型链进行查找,输出truefoo.hasOwnProperty('bar');    //falsefoo.hasOwnProperty('value')   //true

for ... in ... 的遍历中,一般建议使用hasOwnProperty 的方法。

需要注意的是: javascript并没有对hasOwnProperty 做相关的保护,如果恰巧对象有这个叫做hasOwnProperty 的属性,那么产生的结果应该不是我们所期待的。比如像下面这样:

var foo = {  hasOwnProperty: function () { return flase};  bar: '1';};foo.hasOwnProperty('bar') //正如你猜的那样,返回的值永远是false

这时候可能需要做的就是调用外部的hasOwnproperty, 对,就是用call 或者apply。像下面这样:

//返回trueObject.hasOwnProperty.call(foo, 'bar');Object.hasOwnProperty.apply(foo, ['bar']);

原文链接:http://life.rccoder.net/javascript/1207.html

热点阅读

网友最爱