繁体   English   中英

array.splice =这是什么意思?

[英]array.splice = what does it means?

我想了解该代码片段的含义。 “saveTo”是一个数组,程序员为splice方法分配了一个函数()。 我不明白这是什么意思。 这是一个覆盖? return参数的含义是什么?为什么当splice需要2个或更多参数时函数不带参数?

    saveTo.splice = function() {
        if (saveTo.length == 1) {
            $("#send").prop("disabled", true);
        }
        return Array.prototype.splice.apply(this, arguments);
    };

Javascript允许您在运行时重新分配方法。 在这种情况下,程序员正在做的是在这个特定的数组实例上重新分配splice以调用jQuery方法。 除此之外,它的工作方式与现有的splice完全相同,因为它们调用return Array.prototype.splice.apply(this, arguments); - 意味着此方法只传递传递给它的任何arguments

这是一个演示:

 var myArray = [1,2,3,4]; console.log("Splice before re-assing: ", myArray.splice(1,1)); // reset it. myArray = [1,2,3,4]; myArray.splice = function(){ console.log("From inside new splice function"); return Array.prototype.splice.apply(this, arguments); } console.log("Splice after re-assiging: ", myArray.splice(1,1)); 

这是一件好事还是值得商榷的。 它打破了一些编程原则。

编写此代码的程序员知道程序的其他部分正在调用此数组上的splice ,并且他想要附加一个事件,以便更新用户界面(因此调用jQuery)。

这通常被称为“猴子补丁”。 您可以在https://www.audero.it/blog/2016/12/05/monkey-patching-javascript/阅读相关内容。

不是一个好的实践,因为它混淆了正在发生的事情:没有程序员会期望调用数据操作函数在其他地方有副作用。

您可以运行此示例以了解其工作原理:

const myArray = [];

// Patch push method only for this instance of array.
myArray.push = function() {
   // log event
   console.log('myArray.push was called with the following arguments', arguments);

   // Call the original push function with the provided arguments.
   return Array.prototype.push.apply(this, arguments);
}

myArray.push(1);

您还可以为给定类的所有实例修补方法:

// Patch push method on all arrays
const originalPush = Array.prototype.push;
Array.prototype.push = function() {
   // log event
   console.log('.push was called with the following arguments', arguments);

   // Call the original push function with the provided arguments.
   return originalPush.apply(this, arguments);
}

const myArray = [];
myArray.push(1);

至于你关于arguments的问题,在javascript中,所有函数都可以访问包含调用函数的参数的arguments array-like对象,这不依赖于原始声明中指定的参数。

function doSomething(arg1) {
   console.log(arguments[2]);
}

doSomething(1, 2, 3); // outputs "3"

以下是有关它的MDN文档: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

请注意,有一种更好的方法可以在ES6中扩展数组

 class CustomArray extends Array {
   splice(...args) {
      if(this.length === 1) {
         $("#send").prop("disabled", true);
      }
      super.splice(...args);
   }
}

现在还有其他方法可以改变数组长度, .length.pop.shift等,所以那些也应该被覆盖。 然而,调用这些方法的代码不应该只引起副作用,这仍然是有问题的。

这样做是为了专门为saveTo.splice添加一些检查。 如果您调用anyOtherArray.splice ,那么它将按照正常情况进行评估。 它不带参数的原因是因为Array.prototype.splice接受参数,还有saveTo的调用上下文,以及类似于数组的对象arguments ,表示传递给saveTo.splice所有参数。 所以它只是根据特定条件添加了一些额外的代码 - 除此之外,与原生splice没有区别。

1)是的,程序员已经覆盖了拼接方法,不推荐使用它

2)return语句只是调用Array.prototype.splice(原始方法)。

3)是的,splice需要参数,但在JS中,您可能不会将它们定义为函数参数。 您可以将传递的参数作为数组,如arguments内的对象arguments ,如果仔细观察,它们会使用this和arguments对象调用Array.prototype.splice。

好的,让我们一块一块地剖析。

saveTo.splice = function() {
    if (saveTo.length == 1) {
        $("#send").prop("disabled", true);
    }
    return Array.prototype.splice.apply(this, arguments);
};

众所周知,在JavaScript函数中是first class objects ,所以如果我们有一个对象,那么就像saveTo这样:

const saveTo = {};

然后我们可以为其中一个属性分配一个函数,如:

 saveTo.splice = function() {
 };

或类似的东西:

const saveTo = {
   splice: function() {
   }
};

有了这样的方式,你只是调用Array#prototype#splice方法从数组中创建一个浅拷贝,并传递一个iterable它。

所以总的来说,你已经覆盖了原生的Array#prototype#splice以满足你的需求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM