1.3 this 关键字

发布于 2022-05-10 12:49:36 字数 3626 浏览 1079 评论 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

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

0 文章
0 评论
84960 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

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