你如何引用 Array.prototype.slice.call()

How do you reference Array.prototype.slice.call()?

本文关键字:Array prototype slice call 引用 何引用      更新时间:2023-09-26

我正在编写一个脚本,我需要在其中克隆许多不同的位置的数组。 出于这个原因,我想执行以下操作来模拟克隆功能:

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); };

为什么不能直接引用callapply

它不起作用的原因与将对象的方法分配给变量不起作用的原因相同。

如果你调用func.call()那么call里面this将是对func的引用,一个函数对象。

如果将call赋值给变量,则上下文将丢失。您具有对泛型call函数的引用。因此,您必须将正确的上下文(要应用call的方法(作为第一个参数传递到再次call

var clone = [].slice.call;
var arr2 = clone.call([].slice, arr1);

这不是真正的改进,而且相当令人困惑。

callapply 是每个函数从 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]