Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.3 this 关键字 #133

Open
EthanLin-TWer opened this issue Mar 6, 2017 · 0 comments
Open

1.3 this 关键字 #133

EthanLin-TWer opened this issue Mar 6, 2017 · 0 comments
Assignees

Comments

@EthanLin-TWer
Copy link
Owner

this

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

this 不会绑定到...

image

this 会被绑定到…

image

总而言之,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 调用规则的流程图

参考资料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant