调用对象方法时移除this为何会产生不可预测的结果?
为什么移除
this后name[0]的输出变成了J? 先看你提供的代码片段:
const person = { name: ['Bob', 'Smith'], age: 32, gender: 'male', interests: ['music', 'skiing'], bio: function() { console.log(name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); }, greeting: function() { alert('Hi! I\'m ' + name[0] + '.'); } }; person.bio(); person.greeting();
这其实是作用域查找规则加上浏览器的全局特性导致的问题,我给你拆解清楚:
- 当你用
this.name的时候,在对象的方法里,this的指向就是当前的person对象,所以能精准访问到对象内部的name数组['Bob', 'Smith'],取[0]自然就是Bob。 - 但去掉
this直接写name时,JS引擎会顺着作用域链往上找:先看当前函数作用域有没有定义name,找不到就跳到全局作用域。而在浏览器环境里,全局作用域自带一个window.name属性——它是个字符串类型的全局变量,原本是用来设置窗口名称的(比如iframe场景里会用到)。 - 字符串在JS里是类数组结构,支持用下标访问单个字符。你看到的
J,就是当时你的浏览器环境中window.name这个字符串的第一个字符(比如可能之前不小心设置过window.name = "John",或者某些调试环境默认给它赋了以J开头的值)。
你可以自己在浏览器控制台验证一下:
console.log(window.name); // 输出当前全局name的值,它的[0]就是你看到的字符 window.name = "Alice"; console.log(name[0]); // 这时候会输出"A"
说白了就是:没加this的时候,你访问的根本不是person对象里的name数组,而是全局的window.name字符串!
内容的提问来源于stack exchange,提问作者CodeFinity
相关产品推荐
相关产品推荐

