array.splice = 是啥意思?

Posted

技术标签:

【中文标题】array.splice = 是啥意思?【英文标题】:array.splice = what does it means?array.splice = 是什么意思? 【发布时间】:2019-10-10 22:13:00 【问题描述】:

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

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

【问题讨论】:

看来他正在为splice 方法添加他在Array.prototype 中所做的一切。他基本上将他的新 if 语句应用于 Array.prototype 中的 splice 方法。 Check this out 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

编写此代码的程序员知道程序的其他部分正在此数组上调用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

【讨论】:

【参考方案3】:

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

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

现在还有其他方法可以更改数组长度,.length.pop.shift 等,所以这些也应该被覆盖。然而,调用这些方法的代码是否不应该只是造成副作用仍然值得怀疑。

【讨论】:

感谢您的注意,这种方式更具可读性和清晰性。【参考方案4】:

它的作用是添加一些专门针对saveTo.splice 的检查。如果你打电话给anyOtherArray.splice,那么它只会被正常评估。它不带参数的原因是因为Array.prototype.splice 带参数,还有saveTo 的调用上下文,以及类数组对象arguments,代表传递给saveTo.splice 的所有参数。所以它只是根据特定的条件添加了一点额外的代码——除此之外,与原生的splice没有区别。

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:

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

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

【讨论】:

以上是关于array.splice = 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

PPPoE是啥意思,PPPoE是啥意思

“?”是啥意思?在 Erlang 中是啥意思? [复制]

“this”这个词是啥意思,“static”是啥意思?

“||”是啥意思在 var 语句中是啥意思? [复制]

CVE是啥意思,CVE是啥意思

“内容”是啥意思:在招摇/openapi“响应”中是啥意思: