当前位置 主页 > 网站技术 > 代码类 >

    浅谈JS中几种轻松处理'this'指向方式

    栏目:代码类 时间:2019-09-16 10:07

    我喜欢在JS中更改函数执行上下文的指向,也称为 this 指向。

    例如,咱们可以在类数组对象上使用数组方法:

    const reduce = Array.prototype.reduce;function sumArgs() { return reduce.call(arguments, (sum, value) => {  return sum += value; });}sumArgs(1, 2, 3); // => 6

    另一方面,this 很难把握。

    咱们经常会发现自己用的 this 指向不正确。下面的教你如何简单地将 this 绑定到所需的值。

    在开始之前,我需要一个辅助函数execute(func),它仅执行作为参数提供的函数。

    function execute(func) { return func();}execute(function() { return 10 }); // => 10

    现在,继续理解围绕this错误的本质:方法分离。

    1.方法分离问题

    假设有一个类Person包含字段firstName和lastName。此外,它还有一个方法getFullName(),该方法返回此人的全名。如下所示:

    function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = function() {  this === agent; // => true  return `${this.firstName} ${this.lastName}`; }}const agent = new Person('前端', '小智');agent.getFullName(); // => '前端 小智'

    可以看到Person函数作为构造函数被调用:new Person('前端', '小智')。 函数内部的 this 表示新创建的实例。

    getfullname()返回此人的全名:'前端 小智'。正如预期的那样,getFullName()方法内的 this 等于agent。

    如果辅助函数执行agent.getFullName方法会发生什么:

    execute(agent.getFullName); // => 'undefined undefined'

    执行结果不正确:'undefined undefined',这是 this 指向不正确导致的问题。

    现在在getFullName() 方法中,this的值是全局对象(浏览器环境中的 window )。 this 等于 window,${window.firstName} ${window.lastName} 执行结果是 'undefined undefined'。

    发生这种情况是因为在调用execute(agent.getFullName)时该方法与对象分离。 基本上发生的只是常规函数调用(不是方法调用):

    execute(agent.getFullName); // => 'undefined undefined'// 等价于:const getFullNameSeparated = agent.getFullName;execute(getFullNameSeparated); // => 'undefined undefined'

    这个就是所谓的方法从它的对象中分离出来,当方法被分离,然后执行时,this 与原始对象没有连接。

    为了确保方法内部的this指向正确的对象,必须这样做

    以属性访问器的形式执行方法:agent.getFullName() 或者静态地将this绑定到包含的对象(使用箭头函数、.bind()方法等)

    方法分离问题,以及由此导致this指向不正确,一般会在下面的几种情况中出现:

    回调

    // `methodHandler()`中的`this`是全局对象setTimeout(object.handlerMethod, 1000);

    在设置事件处理程序时

    // React: `methodHandler()`中的`this`是全局对象<button onClick={object.handlerMethod}> Click me</button>

    接着介绍一些有用的方法,即如果方法与对象分离,如何使this指向所需的对象。

    2. 关闭上下文

    保持this指向类实例的最简单方法是使用一个额外的变量self:

    function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; const self = this; this.getFullName = function() {  self === agent; // => true  return `${self.firstName} ${self.lastName}`; }}const agent = new Person('前端', '小智');agent.getFullName();    // => '前端 小智'execute(agent.getFullName); // => '前端 小智'