这是前端面试问题系列的第 5 个问题。如果您希望提高准备水平或保持最新状态,请考虑注册前端训练营。
this 关键字始终引用函数或脚本的当前上下文。
对于我们大多数人来说,这是一个令人困惑的话题(双关语),但事实并非如此。您所需要做的就是记住一些规则。
以下规则(按优先顺序排列)规定了运行时如何确定 this 的值:
如果使用 new 关键字调用函数,则函数内的 this 指的是新创建的对象实例。
function Book(title) { console.log(this); this.title = title; console.log(this); } const book1 = new Book('Jungle Book'); // {} // { title: "'Jungle Book' }" console.log(book1.name); // 'Jungle Book'
call()、apply() 或 bind() 可用于在函数内显式设置 this 的值。
const obj = { name: 'Ben' }; function sayHello() { console.log(`Hello, ${this.name}!`); } const sayHelloToBen = sayHello.bind(obj); sayHelloToBen(); // Hello, Ben! sayHello.call(obj); // Hello, Ben! sayHello.apply(obj); // Hello, Ben!
如果函数是对象的方法,则 this 引用该对象。
const person = { name: 'Ben', logThis: function() { console.log(this); } } person.logThis(); // { name: 'Ben', logThis: fn() }
如果在全局上下文中调用函数,则 this 引用全局对象(在非严格模式下)或 undefined(在严格模式下)。
对于浏览器来说,全局对象是window。
// Browser function showThis() { console.log(this); } showThis(); // Window { open: fn, alert: fn, ... }
当一个函数在全局上下文中声明时,它就成为 window 对象的一个属性。调用 window.showThis() 将产生相同的结果。这就是为什么它是隐式方法调用。 (参考上面这条规则)
如果适用多个规则,则优先级较高的规则将适用。
const obj1 = { value: 1, showThis: function() { console.log(this); }, }; const obj2 = { value: 2 }; obj1.showThis.call(obj2); // { value: 2 }
在上面的示例中,应用了两个规则:方法调用和显式绑定。由于显式绑定具有更高的优先级,因此可以设置 this 的值。
箭头函数不遵循上述规则,因为它们没有自己的 this 值。他们从父范围中选择这个值。
const person = { name: 'Ben', showThis: () => { console.log(this); }, showThisWrapped: function() { const arrowFn = () => console.log(this); arrowFn(); } } person.showThis(); // Window { open: fn, alert: fn, ... } person.showThisWrapped(); // { name: 'Ben', showThis: fn, showThisWrapped: fn }
这就是为什么您应该避免对事件侦听器使用箭头函数。事件监听器将 HTML 元素绑定到 this 值,但如果处理程序是箭头函数,则不可能。
function Book(title) { console.log(this); this.title = title; console.log(this); } const book1 = new Book('Jungle Book'); // {} // { title: "'Jungle Book' }" console.log(book1.name); // 'Jungle Book'
喜欢你刚刚读到的内容吗?考虑加入前端训练营的候补名单✌️
以上是JavaScript 中的 `this` 解释的详细内容。更多信息请关注PHP中文网其他相关文章!