简体   繁体   English

array.splice =这是什么意思?

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

I would like to understand the meaning of that code fragment. 我想了解该代码片段的含义。 "saveTo" is a array, the programmer assigned a function() to the splice method. “saveTo”是一个数组,程序员为splice方法分配了一个函数()。 I don't understand what does it mean. 我不明白这是什么意思。 Is that a override? 这是一个覆盖? What is the meaning of the return argument?, and why the function takes no argument while splice requires 2 or more arguments? return参数的含义是什么?为什么当splice需要2个或更多参数时函数不带参数?

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

Javascript lets you re-assign methods at runtime. Javascript允许您在运行时重新分配方法。 In this case, what the programmer was doing is reassigning splice on this specific instance of an array in order to call a jQuery method. 在这种情况下,程序员正在做的是在这个特定的数组实例上重新分配splice以调用jQuery方法。 Beyond that, it works in exactly the same way as the existing splice as they are calling return Array.prototype.splice.apply(this, arguments); 除此之外,它的工作方式与现有的splice完全相同,因为它们调用return Array.prototype.splice.apply(this, arguments); - meaning that this method just passes on whatever arguments are passed to it. - 意味着此方法只传递传递给它的任何arguments

Here's a demo: 这是一个演示:

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

Whether this is a good thing to do is debatable. 这是一件好事还是值得商榷的。 It breaks a few principles of programming. 它打破了一些编程原则。

The programmer that wrote this code knew that some other part of the program is calling splice on this array, and he wanted to attach an event to that, in order to update the user interface (hence the call to jQuery). 编写此代码的程序员知道程序的其他部分正在调用此数组上的splice ,并且他想要附加一个事件,以便更新用户界面(因此调用jQuery)。

This is commonly called "Monkey Patching". 这通常被称为“猴子补丁”。 You can read about it at https://www.audero.it/blog/2016/12/05/monkey-patching-javascript/ 您可以在https://www.audero.it/blog/2016/12/05/monkey-patching-javascript/阅读相关内容。

This is not a good pratice as it obfuscate what is happening: no programmer would expect that calling a data manipulation function has side-effects somewhere else. 不是一个好的实践,因为它混淆了正在发生的事情:没有程序员会期望调用数据操作函数在其他地方有副作用。

You can run this sample to understand how it works: 您可以运行此示例以了解其工作原理:

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

You can also patch methods for all instances of a given class: 您还可以为给定类的所有实例修补方法:

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

As for your question about the arguments , in javascript all functions can access the arguments array-like object that contains the arguments the function was called with, which does not depend on which arguments are specified in the original declaration. 至于你关于arguments的问题,在javascript中,所有函数都可以访问包含调用函数的参数的arguments array-like对象,这不依赖于原始声明中指定的参数。

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

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

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

Note that there is a better way to extend arrays in ES6: 请注意,有一种更好的方法可以在ES6中扩展数组

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

Now that there are other ways to change the arrays length, .length , .pop , .shift , etc. so those should be overriden as well. 现在还有其他方法可以改变数组长度, .length.pop.shift等,所以那些也应该被覆盖。 However then it is still questionable wether the code calling those methods should not just cause the side effect. 然而,调用这些方法的代码不应该只引起副作用,这仍然是有问题的。

What this does is it adds some checks for specifically saveTo.splice . 这样做是为了专门为saveTo.splice添加一些检查。 If you call anyOtherArray.splice , then it'll just be evaluated as per normal. 如果您调用anyOtherArray.splice ,那么它将按照正常情况进行评估。 The reason it takes no arguments is because Array.prototype.splice takes arguments, and also the calling context of saveTo , as well as the array-like objects arguments , representing all the arguments passed to saveTo.splice . 它不带参数的原因是因为Array.prototype.splice接受参数,还有saveTo的调用上下文,以及类似于数组的对象arguments ,表示传递给saveTo.splice所有参数。 So it's just adding a little bit of extra code based on a specific condition - other than that, there's no difference to the native splice . 所以它只是根据特定条件添加了一些额外的代码 - 除此之外,与原生splice没有区别。

1) Yes, the programmer has overridden splice method, its not recommended 1)是的,程序员已经覆盖了拼接方法,不推荐使用它

2) return statement is nothing but calls Array.prototype.splice(the original method). 2)return语句只是调用Array.prototype.splice(原始方法)。

3) Yes, splice requires arguments, but in JS, you may not define them as function params. 3)是的,splice需要参数,但在JS中,您可能不会将它们定义为函数参数。 You get the passed parameters as an array like object arguments inside your functions, if you look closely, they call Array.prototype.splice with this and arguments object. 您可以将传递的参数作为数组,如arguments内的对象arguments ,如果仔细观察,它们会使用this和arguments对象调用Array.prototype.splice。

Okay, let's dissect this piece by piece. 好的,让我们一块一块地剖析。

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

As we all know that in JavaScript functions are first class objects , so if we have an object let's say saveTo something like this: 众所周知,在JavaScript函数中是first class objects ,所以如果我们有一个对象,那么就像saveTo这样:

const saveTo = {};

Then we can assign a function to one of its properties like : 然后我们可以为其中一个属性分配一个函数,如:

 saveTo.splice = function() {
 };

or something like this to: 或类似的东西:

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

With that out of the way, you are just calling the Array#prototype#splice method to create a shallow copy out of the array and passing it an iterable to it. 有了这样的方式,你只是调用Array#prototype#splice方法从数组中创建一个浅拷贝,并传递一个iterable它。

So in total you have overridden the native Array#prototype#splice to fit your requirement. 所以总的来说,你已经覆盖了原生的Array#prototype#splice以满足你的需求。

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

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