我想了解该代码片段的含义。 “ saveTo”是一个数组,程序员将一个function()分配给了splice方法。我不明白这是什么意思。这是优先吗? return参数的含义是什么?为什么函数在拼接需要2个或更多参数的情况下不接受任何参数?
saveTo.splice = function() {
if (saveTo.length == 1) {
$("#send").prop("disabled", true);
}
return Array.prototype.splice.apply(this, arguments);
};
答案 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
来满足您的要求。