你如何引用 Array.prototype.slice.call()
How do you reference Array.prototype.slice.call()?
我正在编写一个脚本,我需要在其中克隆许多不同的位置的数组。 出于这个原因,我想执行以下操作来模拟克隆功能:
var clone = [].slice.call;
var arr1 = [1,2,3,4,5,6,7,8,9,10];
var arr2 = clone(arr1, 0);
不幸的是,上面的代码导致:TypeError: object is not a function
. 我意识到有很多函数可以进行深度克隆和浅拷贝,但我只想使用内置方法。 有趣的是,以下内容确实有效:
var clone = [].slice;
var arr1 = [1,2,3,4,5,6,7,8,9,10];
var arr2 = clone.call(arr1, 0);
有谁知道为什么第一个块不起作用而第二个块不起作用? 有没有办法引用函数调用并应用函数而不会在调用引用的函数时引发错误?
我必须绝对同意Felix King和pimvdb的观点。 我认为使用 Function.protoytpe.bind(( 函数的唯一缺点是这不是所有浏览器(例如 IE6(都可用的函数。 另一种方法是使用提供 curry(( 函数的 JavaScript 库。 另一种选择是定义一个函数,使您能够检索任何其他函数的调用函数。 这是我在我的博客上发布的这样一个函数的定义,我称之为getCall((:
Function.prototype.getCall = function() {
var realFn = this;
return function(objThis) {
return realFn.apply(objThis, Array.prototype.slice.call(arguments, 1));
};
};
现在,使用此定义,您可以执行以下操作来获取对切片函数的调用函数的引用:
var slice = [].slice.getCall();
您可以通过直接调用slice
来克隆数组:
var arr2 = arr1.slice();
如果你想要一个clone
函数,你可以做:
var clone = function(arr) { return arr.slice(); };
如果你真的想对函数进行原型设计(只要函数没有被覆盖,就没有必要(:
var clone = function(arr) { return [].slice.call(arr); };
为什么不能直接引用call
或apply
?
它不起作用的原因与将对象的方法分配给变量不起作用的原因相同。
如果你调用func.call()
那么call
里面this
将是对func
的引用,一个函数对象。
如果将call
赋值给变量,则上下文将丢失。您具有对泛型call
函数的引用。因此,您必须将正确的上下文(要应用call
的方法(作为第一个参数传递到再次call
:
var clone = [].slice.call;
var arr2 = clone.call([].slice, arr1);
这不是真正的改进,而且相当令人困惑。
call
和 apply
是每个函数从 Function.prototype
继承的方法。函数没有自己的版本。 [].slice.call === [].splice.call
产生true
.
区别在于函数的范围,即"this"是什么。我不确定正确的技术术语是什么,但是当函数被称为"独立"或作为对象的属性时,"this"是不一样的。
var myObj = {};
myObj.foo = function () {
console.log(this.bar);
};
myObj.bar = 1234;
var fooRef = myObj.foo;
myObj.foo(); // 1234
fooRef(); // undefined
但是,您可以创建一个函数来包装对该函数的调用并传递所有参数:
var fooEncapsulated = function () {
return myObj.foo.apply(myObj, arguments);
}
fooEncapsulated(); // 1234
作为记录,最常见的方法是:
Array.prototype.slice.call(myArray, other, arguments, here);
问题是whatever_function.call
等于Function.prototype.call
。因此,您可以有效地保存对Function.prototype.call
的引用,并且它是切片函数的信息将丢失。
将其与自定义函数进行比较:
Function.prototype.custom = function() { console.log(this) };
[].slice.custom(); // logs slice function
var ref = [].slice.custom;
ref(); // logs window object
防止this
值被更改的方法是使用 Function.prototype.bind
:
var ref = [].slice.call.bind([].slice);
现在
ref([1,2,3], 1); // [2, 3]
因为在调用.call
函数时,this
值绑定到切片函数,一切都按预期工作。
甜蜜而简单:
slice = Function.prototype.call.bind(Array.prototype.slice);
slice([1,2,3]); // [1,2,3]
slice({length:3,0:1,1:2,2:3}); // [1,2,3]
- 如何迭代Array.prototype函数
- 为什么可以't我用Set对象调用Array.prototype.map
- 复选框:使用Array.prototype.forEach调用推送选中订单,
- 转换类似数组的对象Array.prototype.slice或Array.from
- 为什么要将Array.prototype.slice.call与参数一起使用
- 为什么 Array.prototype.reduce() 不接受 Map 对象作为初始值
- 如何在返回单个对象时递归使用 Array.prototype.find()
- 如果 Array.prototype.map() 没有返回,它是否被正确使用
- Array.prototype.fill() different from fill as I go
- moment:Array.prototype.some在null或未定义时被调用
- Array.prototype.stice.call()的内部工作
- Array.prototype.splice.call-不适用于querySelectorAll('.class
- Array.prototype.reduce的实际用途是什么
- "可变变量可从闭包“”访问;在传递给Array.prototype.every的函数中
- [].slice vs Array.prototype.slice
- 使用Javascript的高级Array.prototype.filter
- ES6 Array.prototype.values should'它现在还不存在
- 为什么Array.prototype不是Array的实例
- Array.prototype.slice.call如何在getElementsByClassName的重新创建中工作
- 为什么使用Array.prototype.map.call而不是Array.map.call