为何var/let声明name对象时,函数call调用输出结果不同?
为什么var和let声明name对象会导致call调用结果不同?
两段代码仅在声明name对象时分别使用var和let关键字,但调用pname.call(name)后的输出完全不同,核心原因是浏览器全局作用域的内置name属性与变量声明规则的冲突:
关键细节拆解
- 浏览器环境中,全局对象
window自带一个内置的name属性,它的作用是存储窗口名称,并且只能是字符串类型。 - 用
var声明全局变量时,变量会直接挂载到window对象上。当你执行var name = {firstname:'abc', lastName:'xyz'}时,其实是在修改window.name的值——但因为window.name只能存字符串,JS会自动把你定义的对象转换成字符串"[object Object]"。此时调用pname.call(name),传入的name是这个字符串值,字符串的包装对象里根本没有firstname和lastName属性,所以输出undefined undefined。 let声明的全局变量不会挂载到window对象上,属于独立的块级作用域变量。所以let name = {firstname:'abc', lastName:'xyz'}创建的就是你定义的原始对象,pname.call(name)时this指向该对象,能正常读取属性,输出abc xyz。
代码对比
Snippet 1(var声明)
var name={ firstname:'abc', lastName:'xyz' } let pname= function(){ console.log(this.firstname+' '+this.lastName); } pname.call(name); // OUTPUT: undefined undefined
Snippet 2(let声明)
let name={ firstname:'abc', lastName:'xyz' } let pname= function(){ console.log(this.firstname+' '+this.lastName); } pname.call(name); // OUTPUT: abc xyz
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

