在 JavaScript 的开发中,this 这个关键字一直都是一个比较棘手的问题。尤其是在 ES5 的时候,大家都需要使用函数的方法来绕过它。不过,ES6 中出现的箭头函数,让我们能够更加简单地理解以及处理 this 指针的问题。本文将详细讲解ES6 箭头函数中this 指针问题的原因以及解决方式。
问题描述
在 JavaScript 中,this 这个关键字通常被用来访问当前对象。然而,在不同的上下文环境中,this 的含义会有所不同,这里就会引发一些问题。
一个比较常见的问题是,this 的值是在函数被调用时才被确定的。当我们使用一个函数不同的方式来调用时,this 的指向可能会发生改变。例如,下面这个示例中:
-- -------------------- ---- ------- --- ------ - - ----- ------- ------ ---------- - ---------------- -- ---- -- - - ----------- - -- --- -------- - ------------- ----------- -- --- -- ---- -- ---------
在这个例子中,我们期望输出的字符串应该是 "Hi, my name is John",但是实际上却是 "Hi, my name is undefined" 。这是因为在调用 sayHello 函数时,函数的上下文环境已经发生改变,此时 this 的指向已经不再是 person 对象了。
解决方案一:使用 Function.prototype.bind()
为了绕过上述问题,在 ES5 语法中,我们通常会通过在内部函数中使用 var self = this; 或者 Function.prototype.bind 方法来保存合适的 this 值。例如:
-- -------------------- ---- ------- --- ------ - - ----- ------- ------ ---------- - ---------------- -- ---- -- - - ----------- - -- --- -------- - -------------------------- ----------- -- --- -- ---- -- ----
在这个例子中,我们使用 Function.prototype.bind 将 person 对象作为 sayHi 函数的上下文环境,并初始化 sayHello 函数以此绕过 this 指向的问题。
解决方案二:使用箭头函数
在 ES6 中,我们可以使用箭头函数来轻松地处理 this 指向的问题。箭头函数的 this 值是从父级代码块(如代码中的 sayHi 函数)中继承而来的。因此,不需要在内部函数中保存 this 值或使用 Function.prototype.bind 就可以正确地访问 this 值。
-- -------------------- ---- ------- --- ------ - - ----- ------- ------ ---------- - ------------- -- - ---------------- -- ---- -- - - ----------- -- ------ - -- --------------- -- --- -- ---- -- ----
在这个例子中,我们定义了一个 setTimeout 函数调用,并使用箭头函数作为回调函数。由于箭头函数中的 this 值始终是从父级代码块中继承而来的,所以箭头函数正确地访问了 person 对象的 name 属性。
注意,箭头函数可以使得代码更加简洁,但有时候也会带来一些混淆和错误。例如,在一个非箭头函数中可以使用 arguments 变量获取函数参数,但是在箭头函数中却不能这么做。因此,在选择是否使用箭头函数时,需要仔细权衡其优缺点。
结论
在 ES6 中,箭头函数使得使用 this 值更加方便。由于箭头函数继承了其父级代码块的 this 值,因此我们不再需要使用 Function.prototype.bind 方法或者保存 this 值的变量来避免 this 指向的问题。当然,在比较老的浏览器中可能不支持箭头函数,所以我们也需要在这些环境下使用传统的方式来处理 this 指向的问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/671f98312e7021665efea2aa