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 = 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章