array.splice =什么意思?

时间:2019-05-24 10:06:25

标签: javascript jquery arrays function

我想了解该代码片段的含义。 “ saveTo”是一个数组,程序员将一个function()分配给了splice方法。我不明白这是什么意思。这是优先吗? return参数的含义是什么?为什么函数在拼接需要2个或更多参数的情况下不接受任何参数?

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

6 个答案:

答案 0 :(得分:4)

JavaScript使您可以在运行时重新分配方法。在这种情况下,程序员正在做的是在此特定于数组的实例上重新分配splice以便调用jQuery方法。除此之外,它的工作方式与它们调用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));

这是否是一件好事还是有争议的。它打破了一些编程原则。

答案 1 :(得分:2)

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

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

现在,还有其他方法可以更改数组的长度.length.pop.shift等,因此也应将其覆盖。但是,如果调用这些方法的代码不仅仅会引起副作用,那仍然是一个问题。

答案 2 :(得分:1)

它的作用是专门为saveTo.splice添加了一些检查。如果您呼叫anyOtherArray.splice,它将按照常规进行评估。它不带参数的原因是因为Array.prototype.splice带有参数,还有saveTo的调用上下文以及表示传递给{{的所有参数的类似数组的对象arguments 1}}。因此,它只是根据特定条件添加了一些额外的代码-除此之外,与本机saveTo.splice没什么区别。

答案 3 :(得分: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类似数组的对象,该对象包含调用该函数所使用的参数,而与指定的参数无关在原始声明中。

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

答案 4 :(得分:1)

1)是,程序员已重写了拼接方法,不推荐使用

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

3)是的,拼接需要参数,但是在JS中,您可能无法将其定义为函数参数。您可以在函数内部将传递的参数作为类似于对象arguments的数组来获取, 如果仔细观察,他们会使用此对象和arguments对象调用Array.prototype.splice。

答案 5 :(得分:1)

好吧,让我们逐一剖析。

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来满足您的要求。