JavaScript中Function.prototype.bind()复合使用的异常问题求助
搞定Function.prototype.bind()的坑:新手必懂的硬绑定逻辑
哥们,我太懂你作为JS新手刚接触bind时的懵圈了——我当年第一次用bind写嵌套函数时,也对着不符合预期的结果挠了半天头!结合你给出的测试代码片段,我帮你拆解下问题出在哪,以及怎么解决。
先把你的测试代码补全(方便分析)
看你没写完的代码,我大概补全成最接近的场景:
(function () { this.t = 9.8765432 this.a = (function(){ this.t = 3.14159 this.b = (function(){return this.t;}).bind(this) this.c = (function(){ this.t=1.23456 this.d=(function(){return this.t;}).bind(this) return this.d() })() })() })()
问题核心:bind是「硬绑定」,一旦绑定就锁死this
这是新手最容易踩的坑:bind返回的新函数,它的this指向是永久固定的——绑定的时候指向哪个对象,之后不管你怎么调用这个新函数(哪怕用call/apply强行改this都没用),它的this都不会变。
举个例子:
- 你在
a函数里把b绑定到了当前的this(此时这个this是全局对象,this.t=3.14159) - 之后
c函数执行时,修改了全局对象的t为1.23456,但b的this早就被bind锁死在绑定那一刻的全局对象(当时t是3.14159),所以调用b()还是会返回3.14159,而不是你预期的1.23456。
额外提醒:多层自执行函数的this默认指向全局
你的代码里用了多层自执行函数(function(){})(),如果没有用call/apply改变this,这些函数里的this默认都是指向全局对象(浏览器里是window,Node.js里是global)。所以你每次修改this.t,其实都是在修改全局变量的t,这也容易导致变量污染和预期外的结果。
符合预期的两种解决方法
如果你想要动态获取最新的t值,而不是绑定那一刻的值,可以试试这两种方案:
方案1:用箭头函数替代bind(推荐)
箭头函数没有自己的this,它的this是继承自外层作用域的this,是动态变化的。这样就能拿到最新的t值:
(function () { this.t = 9.8765432 this.a = (function(){ this.t = 3.14159 // 箭头函数继承外层a函数的this,会动态跟随 this.b = () => this.t this.c = (function(){ this.t=1.23456 this.d = () => this.t console.log(this.d()) // 输出 1.23456 })() console.log(this.b()) // 输出 1.23456(拿到最新的t值) })() })()
方案2:用闭包保存变量
把需要访问的t存在一个变量里,通过闭包来访问,避开this绑定的问题:
(function () { this.t = 9.8765432 this.a = (function(){ const currentThis = this // 把当前this存进变量 currentThis.t = 3.14159 this.b = function(){ return currentThis.t } // 闭包访问currentThis this.c = (function(){ currentThis.t=1.23456 // 修改同一个变量的t this.d = function(){ return currentThis.t } console.log(this.d()) // 输出 1.23456 })() console.log(this.b()) // 输出 1.23456 })() })()
内容的提问来源于stack exchange,提问作者FunnyFunkyBuggy
相关产品推荐
相关产品推荐

