为何let关键字实现的代码正常运行,var版本却报TypeError错误?
为什么用var定义的函数会抛出TypeError,而let可以正常运行?
嘿,这个问题的核心藏在JavaScript全局作用域的特性里,咱们掰开揉碎了说:
先聊var出问题的原因
当你在全局作用域用var声明变量时,这个变量会自动挂载到全局对象上——在浏览器环境里,这个全局对象就是window。
但尴尬的是,window本身自带一个内置属性window.name,这个属性专门用来存储当前浏览器窗口的名称,而且它的类型被限定为字符串。哪怕你试图给它赋值一个函数,浏览器也会自动把这个函数转成字符串格式。
所以当你写:
var name = function () { console.log('my name is Sid'); } var age = function (str1) { str1(); } age(name);
实际发生的是:
var name把变量挂到了window.name上- 你赋值的函数被强制转成了字符串(变成
"function () { console.log('my name is Sid'); }") - 调用
age(name)时,传递的其实是这个字符串,而不是函数,执行str1()自然就会报错“Uncaught TypeError: str1 is not a function”
再看let能正常运行的原因
let是ES6新增的声明方式,它声明的全局变量不会被挂载到全局对象上,属于块级作用域的独立变量,完全不会和window的内置属性name产生冲突。
所以你用let name定义的函数就是一个正经的函数类型变量,传递给age后,str1()自然能正常执行函数调用。
验证一下这个逻辑
你可以自己跑一下这段代码看看差异:
// 测试var的情况 var name = function() { console.log('test'); }; console.log(typeof window.name); // 输出 "string" console.log(name === window.name); // 输出 true,说明name就是window.name // 测试let的情况 let name2 = function() { console.log('test'); }; console.log(typeof name2); // 输出 "function" console.log(window.name2); // 输出 undefined,说明let声明的变量没挂到window上
内容的提问来源于stack exchange,提问作者sid
相关产品推荐
相关产品推荐

