js函数内部,如何访问所有实参?arguments对比...args
发布于 作者:苏南大叔 来源:程序如此灵动~目标是在JavaScript
函数内部直接获得该函数的所有实参,以往的经验是直接访问arguments
变量即可。然而,故事就是从这里开始的。值得特别说明的是:本文的代码可能会因为运行环境的不同(比如纯node
或者浏览器环境),而产生比较巨大的差异性。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验文章。测试环境:chrome@131.0.6778.70
,nodejs@20.18.0
。
正常版本的 arguments
正常情况下,在函数内部,可以直接通过arguments
这个系统变量,拿到参数列表的。参考代码:
function sunan() {
console.log(arguments);
}
sunan("su", "nan", "dashu");
参考文章:
特殊情况:箭头(匿名)函数
箭头函数就是匿名函数,在本文语境中,两者是等价的。在箭头函数里面,这个万能的arguments
方案失效了。箭头函数不会创建自己的arguments
对象。
let sn = () => {
console.log(arguments);
};
sn("su","nan","dashu");
(()=>{
console.log(arguments);
})("su","nan","dashu");
上述两个代码,在浏览器环境下,直接提示arguments is not defined
。在纯node
环境下,变成了一堆莫名其妙的东东。
新的救世主:...args
这个...
通常理解为解构。但是,在本文的代码里面,苏南大叔把...args
理解为剩余参数。参考文章:
参考代码:
function sunan(p1, ...args) {
console.log(args);
}
sunan("su", "nan", "dashu");
let sn = (p1, ...args) => {
console.log(args);
};
sn("su", "nan", "dashu");
((p1, ...args) => {
console.log(args);
})("su", "nan", "dashu");
如果把“剩余参数”之外的参数都设置为没有,那么“剩余参数”就是“全部参数”了。本文的这种特殊用法,就是这么来的。
function sunan(...args) {
console.log(args);
}
sunan("su", "nan", "dashu");
let sn = (...args) => {
console.log(args);
};
sn("su", "nan", "dashu");
((...args) => {
console.log(args);
})("su", "nan", "dashu");
...args 更多使用场景
在.call()/.apply()/.bind()
里面,这个...args
得到了很好的应用。在形参里面,三个点就是“剩余参数”的意思。在执行函数的时候,三个点就是解包,把数组解压成独立的变量的意思。
参考代码:
function test(p1, p2, p3) {
console.log(p1, p2, p3);
}
function susu(...args) {
// 原版
test(args[0], args[1], args[2]);
test(...args);
// call
test.call({}, args[0], args[1], args[2]);
test.call({}, ...args);
// apply
test.apply({}, [args[0], args[1], args[2]]);
test.apply({}, args);
test.apply({}, [...args]);
// bind
test.bind({}, args[0], args[1], args[2])();
test.bind({})(args[0], args[1], args[2]);
test.bind({}, ...args)();
test.bind({})(...args);
}
susu("su", "nan", "dashu");
执行结果,如下图所示:
.call()
/.apply()
/.bind()
的用法,参考文章:
- https://newsn.net/say/js-call.html
- https://newsn.net/say/js-apply.html
- https://newsn.net/say/js-bind.html
这些高级用法,在篡改系统函数的时候,非常有用。参考文章:
- https://newsn.net/say/react-future-flag.html
- https://newsn.net/say/history-event-listen.html
- https://newsn.net/say/js-hook.html
特殊情况
下面的代码中,和本文的主体内容很相似。但却是一个不同的用法。
function sn(...args) {
// 这里只接收多个参数,实际传了两个字符串
console.log(args); // [ 'sunan', 'dashu' ]
console.log(...args); // sunan dashu
}
sn("sunan", "dashu");
function sn2(args) {
// 这里只接收一个参数,实际传了一个数组
console.log(args); // [ 'sunan', 'dashu' ]
console.log(...args); // sunan dashu
}
sn2(["sunan", "dashu"]);
结语
从本文的运行结果中,可以看到:...args
比arguments
更靠谱一些。不过,从对函数体本身的破坏程度上看的话,arguments
就几乎没有任何破坏,函数该咋传递还是咋传递。最终的结论:使用...args
吧!
更多苏南大叔的js
相关经验文章,请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。