让我们从The Good Parts
本书中获取这个例子:
Array.method('unshift', function () {
this.splice.apply(this,[0,0].concat(Array.prototype.slice.apply(arguments)));
return this;
});
为什么作者在一个地方使用this.splice
而在另一个地方使用Array.prototype.slice
?
我尝试互相交换this
和Array.prototype
,并收到如下错误:
TypeError: Cannot read property 'slice' of undefined
但我仍然不确定,如何知道何时应该使用this
或Array.prototype
。
答案 0 :(得分:9)
在第一次通话中,this
指的是调用unshift
的数组,因此它会从splice
继承Array.prototype
。
在第二个调用中,代码使用slice
对不的数组(arguments
伪数组,其中没有slice
方法)。因此,在这种情况下,Crockford通过Array.prototype
访问该方法。
从技术上讲,他本可以在第二个位置使用this.slice
,如下所示:
Array.method('unshift', function () {
this.splice.apply(this,[0,0].concat(this.slice.apply(arguments)));
return this;
});
...但它可能会产生误导,因为第二次调用与this
引用的当前数组无关。
答案 1 :(得分:0)
有时可视化关系更容易,因此您意识到在很多情况下我们有foo.bar === Foo.prototype.bar; // true
在创建实例foo
时,构造函数Foo
的 prototype 属性被设置为foo
的特殊引用(__proto__
),如果你试图访问foo
上不存在的属性,那么寻找属性的下一个地方就是通过该引用。
这意味着当您希望foo
没有以隐藏该对象的属性的方式进行修改时,您是否尝试通过foo.bar
或{进行查找并不重要{1}}因为它是一样的。
但是,正如您所看到的,并非所有都具有相同的Foo.prototype.bar
路径,因此您无法假设__proto__
存在,例如。这意味着如果您没有数组实例,但是您想要切片它,您必须引用 slice ,尽管您知道存在的方式,例如obj.slice