为何括号会导致对象失去绑定?Node.js/V8相关技术问询
为什么包裹
new实例化语句后调用方法会抛出TypeError: this.getName is not a function? 嘿,这个问题我太熟了!本质是JavaScript中this的绑定规则和运算符解析顺序在搞鬼,咱们一步步拆解:
先看你的代码示例
function Greeter(name) { this.name = name; } Greeter.prototype.getName = function() { return this.name; } Greeter.prototype.helloWorld = function() { console.log(`Hello ${this.getName()}`); } // 报错的写法: (new Greeter('Alice').helloWorld)(); // TypeError: this.getName is not a function // 正常的写法: new Greeter('Alice').helloWorld(); // 输出 Hello Alice
为什么报错?
咱们先分析两种写法的核心差异:
正常写法
new Greeter('Alice').helloWorld():
JavaScript解析器会优先处理new Greeter('Alice')创建实例,然后通过.调用实例的helloWorld方法。此时helloWorld作为实例方法调用,this自然绑定到Greeter的实例上,所以this.getName()能正常访问原型上的方法。报错写法
(new Greeter('Alice').helloWorld)():
括号在这里把new Greeter('Alice').helloWorld变成了一个独立表达式——也就是先获取实例的helloWorld方法引用,再用()直接调用这个函数。此时helloWorld是作为普通函数被调用的,而非实例方法,this的绑定规则就变了:- 在非严格模式下,
this会绑定到全局对象(浏览器里是window,Node.js里是globalThis); - 在严格模式下,
this会变成undefined。
不管哪种情况,全局对象/undefined都没有getName方法,所以就抛出了TypeError: this.getName is not a function。
- 在非严格模式下,
如果你确实需要用括号包裹实例化语句,怎么写才对?
要是你想明确强调实例化的优先级,正确的写法是把整个实例化表达式用括号包裹,再调用方法:
(new Greeter('Alice')).helloWorld(); // 完全正常,和无括号写法等价
这里的括号只是明确了表达式优先级,但helloWorld仍然是作为实例方法调用,this绑定完全没问题。
总结一下
- 别把方法引用单独用括号包裹后直接调用,这会破坏
this的绑定; - 如果要加括号明确优先级,确保括号只包裹实例化部分,方法调用的
.和()放在括号外面。
内容的提问来源于stack exchange,提问作者Parris
相关产品推荐
相关产品推荐

