简介
假如之间进修过cpp
、java
之类的言语,都邑晓得他们是可以基于类 class
举行继续的, 在JavaScript
中,并没有类继续这个观点,要完成JavaScript
中的继续,须要原型来协助。
比方鄙人面的这段代码中:
function Foo () {
this.value = 1;
};
Foo.prototype = {
method: function () {};
};
//设置Bar的原型为Foo()的实例
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';
//修改Bar的constructor
Bar.prototype.constructor = Bar;
//建立一个Bar的实例
var test = new Bar();
在这段代码中,就一向维护着一个原型链,抽象化的明白起来多是如许的:
test [Bar的实例]
Bar.prototype [Foo的实例]
{foo: 'Hello World!'}
Foo.prototype
{method: function(){}}
Object.prototype
{...}
很好去明白,test 是从Bar.prototype
和 Foo.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; //经由过程全部原型链举行查找,输出true
foo.hasOwnProperty('bar'); //false
foo.hasOwnProperty('value') //true
在for ... in ...
的遍历中,平常发起运用hasOwnProperty
的要领。
须要注重的是: javascript
并没有对hasOwnProperty
做相干的庇护,假如碰巧对象有这个叫做hasOwnProperty
的属性,那末发生的效果应当不是我们所期待的。比方像下面如许:
var foo = {
hasOwnProperty: function () { return flase};
bar: '1';
};
foo.hasOwnProperty('bar') //正如你猜的那样,返回的值永远是false
这时刻能够须要做的就是挪用外部的hasOwnproperty
, 对,就是用call
或许apply
。像下面如许:
//返回true
Object.hasOwnProperty.call(foo, 'bar');
Object.hasOwnProperty.apply(foo, ['bar']);