js关于数组的面试题(JS关于this)

this 关键字是 JavaScript 中最复杂的机制之一。它是一个很特别的关键字,被自动定义在 所有函数的作用域中。但是即使是非常有经验的 JavaScript 开发者也很难说清它到底指向 什么。

实际上,JavaScript 中 this 的机制并没有那么先进,但是开发者往往会把理解过程复杂化, 毫无疑问,在缺乏清晰认识的情况下,this 对你来说完全就是一种魔法。

为什么要用this

js关于数组的面试题(JS关于this)(1)

这段代码可以在不同的上下文对象(me 和 you)中重复使用函数 identify() 和 speak(), 不用针对每个对象编写不同版本的函数

如果不使用 this,那就需要给 identify() 和 speak() 显式传入一个上下文对象。

js关于数组的面试题(JS关于this)(2)

然而,this 提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将 API 设计 得更加简洁并且易于复用。

误解

我们之后会解释 this 到底是如何工作的,但是首先需要消除一些关于 this 的错误认识。

太拘泥于“this”的字面意思就会产生一些误解。有两种常见的对于 this 的解释,但是它 们都是错误的。

指向自身

人们很容易把 this 理解成指向函数自身,这个推断从英语的语法角度来说是说得通的。

那么为什么需要从函数内部引用函数自身呢?常见的原因是递归(从函数内部调用这个函 数)或者可以写一个在第一次被调用后自己解除绑定的事件处理器。

JavaScript 的新手开发者通常会认为,既然函数看作一个对象(JavaScript 中的所有函数都 是对象),那就可以在调用函数时存储状态(属性的值)。这是可行的,有些时候也确实有 用,但是后面即将介绍的许多模式中你会发现,除了函数对象还有许多更合适存储状态 的地方。

我们想要记录一下函数 foo 被调用的次数,思考一下下面的代码:

js关于数组的面试题(JS关于this)(3)

console.log 语句产生了 4 条输出,证明 foo(..) 确实被调用了 4 次,但是 foo.count 仍然 是 0。显然从字面意思来理解 this 是错误的。

执行 foo.count = 0 时,的确向函数对象 foo 添加了一个属性 count。但是函数内部代码 this.count 中的 this 并不是指向那个函数对象,所以虽然属性名相同,根对象却并不相 同,困惑随之产生。

遇到这样的问题时,许多开发者并不会深入思考为什么 this 的行为和预期的不一致,也不 会试图回答那些很难解决但却非常重要的问题。他们只会回避这个问题并使用其他方法来 达到目的,比如创建另一个带有 count 属性的对象。

js关于数组的面试题(JS关于this)(4)

从某种角度来说这个方法确实“解决”了问题,但可惜它忽略了真正的问题——无法理解 this 的含义和工作原理——而是返回舒适区,使用了一种更熟悉的技术:词法作用域

所以,对于我们的例子来说,另一种解决方法是使用 foo 标识符替代 this 来引用函数 对象:

js关于数组的面试题(JS关于this)(5)

然而,这种方法同样回避了 this 的问题,并且完全依赖于变量 foo 的词法作用域。

另一种方法是强制 this 指向 foo 函数对象:

js关于数组的面试题(JS关于this)(6)

这次我们接受了 this,没有回避它。如果你仍然感到困惑的话,不用担心,之后我们会详 细解释具体的原理

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页