1.3 this 关键字

发布于 2022-05-10 12:49:36 字数 3626 浏览 1099 评论 0

this 是一个标识符,会被赋值以指向”当前“对象。目的是为了让你能从语言层面使用这个特性辅助编程,而不需要深入到语法层。不过,这个 当前 对象指向哪里,就没那么好判断了,大侠接坑。

this 不会绑定到...

this 会被绑定到…

总而言之,this 绑定的判定法则为:

  1. 90%的情况下,this 会被绑定至函数调用所在的对象上:函数调用 -> 函数调用标识. -> 其前的对象
  2. 仅与函数调用时刻有关,而非函数定义或声明等无关。详见完整规则5

更加完整的规则为:

  1. 全局调用(fn()):默认绑定到全局对象(浏览器下是 window,NodeJS 下是 global
  2. 作为对象的属性/方法(object.fn()):这种最简单直接、符合直觉,就是绑定到该对象 object
  3. 不是对象的属性,但要调用该函数(fn.call(onAnother, {})):这种也好理解,被调用的函数不是作为对象的属性,没有一个指向对象的 this,因此手动指定其绑定到另一个对象 onAnother
  4. 规则2与规则3同时出现(object.fn.call(onAnother, {})):规则3优先。即此时依然绑定到 onAnother
  5. setTimeout(fn, 1000ms):答案是,与 setTimeout 实现方式有关。因为 fn 中的 this 绑定到哪里,完全取决于其被调用时是以什么方式被调用,而这是取决于 setTimeout 方法的实现的。待会细论
  6. 不在函数之中被使用(console.log(this)):答案也是取决于 JS 引擎的实现。本来按照词法作用域规则,JS 引擎会一直向上查找 this 这个变量,查不到就返回 ReferenceError。但坑就坑在,由于历史原因,有些 JS 引擎会默认帮你绑定到全局对象上去(比如 Chrome 56.0+ 的 V8 5.6+ 引擎),好在现代的引擎已经修正了这个问题(比如 NodeJS 6.9.4 用的 V8 5.1+引擎)。但更坑就坑在,你不知道哪些引擎已经修复了,你的容器用的是哪个引擎。该特性最好少用

规则5中提出了一个重要的问题:回调。传入给回调的函数,你不知道对方会如何调用,因此必须限制 this 关键字的使用,以使代码尽可能少因为对方调用方式而受影响。从你这端进行对象调用是没有用的,因为 this 的绑定仅与运行时被调用的地方有关系。比如:

function fn() { ... }
var object = {}; object.method = fn

// makes no difference
setTimeout(fn, 1000)
setTimeout(object.method, 1000)

最佳实践

需要注意,有些令人困惑的特性可以使用 strict mode 禁用,或已在 ES6 中被修复。需要学习

  1. What are closures
  2. Why we need it/How it solves specific problems
  3. Any scenarios of using
  4. Other programming language implementation and difference?
  5. 绑定规则的官方文档?
  6. JavaScript: The good parts
  7. this 调用规则的流程图

参考资料

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

文章
评论
84963 人气
更多

推荐作者

微信用户

文章 0 评论 0

小情绪

文章 0 评论 0

ゞ记忆︶ㄣ

文章 0 评论 0

笨死的猪

文章 0 评论 0

彭明超

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文