arguments.length

function xxx(a,b,c) {
    console.log(arguments.length)    
}
xxx(1,2)
console.log('arg:',arguments.length)  

第5行代码在控制台运行报错:
Uncaught ReferenceError: arguments is not defined
这点我能理解,符合我的预期结果。
但是,在vscode运行,它居然不报错。
第5行的结果,它报:arg: 5
为什么它不报错的?还有这5是什么来的啊?不可能是arguments.length吧。

刚将第5行代码改为:console.log(arguments)
node.js给我打印了一长串东西,
Node.js与浏览器是不一样的。
的确是不一样的。

阅读 3.1k
2 个回答

Node 中,如果在 package.json 中声明了 "type": "module",直接使用 arguments 会报错:eferenceError: arguments is not defined,而且也不能使用 __filename__dirname


如果没有声明 "type": "module",那就会使用 CommonJS 规范,每个文件都会封装成一个 Module factory(工厂函数)。我没去看规范,但从打印出来的信息来看,

  • 第 0 个参数是个空对象,应该是 exports
  • 第 1 个参数是 require 函数
  • 第 2 个参数是个 Module 对象,应该就是 module
  • 第 3 个参数是当前脚本的全路径,应该是 __filename
  • 第 4 个参数是当前脚本所在的目录,应该是 __dirname

所以整个脚本文件会被封装成这样的形式:

function (exports, require, module, __filename, __dirname) {
    ...
} 

参数变量就是平时写程序时用的所谓的“全局变量”。

实际在 CommonJS 中大概应该是这样的(只是示意,有兴趣自己去找源码看):

let module = getModule("xxxx.js");
if (!module) {
    module = new Module();
    getFactory("xxxx.js")(module.exports, require, module, filename, dirname);
}

Node.js里一个文件也是一个模块,每个文件最终在执行被包装成这样的一个形式:

function (exports, require, module, __filename, __dirname) {
    xxxx
}

你这里执行console.log(arguments)(在函数外部)的时候,拿到的就是

exports, require, module,__filename, __dirname

这5个参数,所以打印出来的长度是5。

你可以执行下(在函数外部)

console.log('arg:',arguments.callee + "")  然后就可以看到最终被执行的代码的样子
function (exports, require, module, __filename, __dirname) {
    function xxx(a,b,c) {
        console.log(arguments.length)
        console.log(arguments)
    
    }
    xxx(1,2)
    console.log('arg:',arguments)
    console.log('arg:',arguments.callee + "")
    
    console.log('arg:',arguments.length)
}

你可以执行下(在函数外部)

console.log('arg:',arguments)  打印出来就可以看到5个参数具体的值

arguments 对象具体的属性描述,MDN文档

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题