Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

自带 bind 的方法定义

  当我们希望将某个对象的方法作为回调使用时就会遇到 this 指向错误的问题。因为函数如果不是基于对象调用就会失去 this 绑定。这时候我们可能要通过 bind 方法来解决这个问题。但一些方法被作为回调非常频繁,每次都手动去调用 bind 就太麻烦了,有没有办法一次搞定呢?
  具体问题可以看下面的代码: <script> var A = function() {}; A.prototype = []; var a = new A(); // setTimeout(a.push, 100, 233); // 错误的用法 setTimeout(a.push.bind(a), 100, 233); </script>   这里只是把 push 传进去作为回调,它丢失了 a 的绑定,于是这个代码可能会把 233 这个数据 push 到 window 上,因为非严格模式下空 this 绑定会指向 global,在浏览器上就是 window。正确的用法是 a.push.bind(a),然而这个代码看起来太恶心了。那么有没有什么办法可以优雅地解决这个问题呢?
  一个简单的方法是在 A 的构造器中做一次 bind,比如这样 <script> var A = function() { this.push = this.push.bind(this); }; A.prototype = []; var a = new A(); setTimeout(a.push, 100, 233); </script>   首先,这个代码依然很恶心。然而这个代码要改变 A 的构造器,这可能并不容易。而且这个代码需要给实例添加一个名为 push 的 own property,这可能代理一些副作用。那么,还有更优雅的解决方案么?也许有吧?如果 push 这个方法被从 a 中取出时做一次临时的 bind 不就解决了么?于是可以有 <script> var A = function() {}; A.prototype = []; Object.defineProperty(A.prototype, 'push', { get: function() { return [].push.bind(this); } }); var a = new A(); setTimeout(a.push, 100, 233); </script>
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^