代码之家  ›  专栏  ›  技术社区  ›  Nish

对象[重复]上回调的作用域和“this”

  •  -1
  • Nish  · 技术社区  · 2 年前

    我在几个地方读到过,关键的区别在于 this 在箭头函数中进行词汇绑定。这很好,但我不知道那是什么意思。

    我知道这意味着它在定义函数体的大括号范围内是唯一的,但我实际上无法告诉您以下代码的输出,因为我不知道是什么 是指,除非是指fat arrow函数本身。。。。这似乎没什么用。

    var testFunction = () => { console.log(this) };
    testFunction();
    
    0 回复  |  直到 4 年前
        1
  •  44
  •   Dave    9 年前

    Arrow functions capture the this value of the enclosing context

    function Person(){
      this.age = 0;
    
      setInterval(() => {
        this.age++; // |this| properly refers to the person object
      }, 1000);
    }
    
    var p = new Person();
    

    所以,为了直接回答你的问题, 在arrow函数内部,它的值与分配arrow函数之前的值相同。

        2
  •  24
  •   user6445533 user6445533    8 年前

    为了提供全局,我将同时解释动态绑定和词汇绑定。

    动态名称绑定

    this 引用调用该方法的对象。这是一个经常被读的句子。但它仍然只是一个短语,相当抽象。这个句子有对应的代码模式吗?

    是的,有:

    const o = {
      m() { console.log(this) }
    }
    
    // the important patterns: applying methods
    
    o.m(); // logs o
    o["m"](); // logs o
    

    m 是一种方法,因为它依赖于 . o.m() o["m"]() 方法 m级 应用于 o . 这些模式是Javascript对我们著名短语的翻译。

    您应该注意另一个重要的代码模式:

    "use strict";
    
    const o = {
      m() { console.log(this) }
    }
    
    // m is passed to f as a callback
    function f(m) { m() }
    
    // another important pattern: passing methods
    
    f(o.m); // logs undefined
    f(o["m"]); // logs undefined
    

    它与前面的模式非常相似,只缺少括号。但后果是相当严重的:当你通过 m级 到函数 f ,你退出 m级 其对象/上下文的 o . 它现在被连根拔起 未引用任何内容(假定为严格模式)。

    词法(或静态)名称绑定

    箭头函数没有自己的 / super / arguments 结合它们从其父词法作用域继承它们:

    const toString = Object.prototype.toString;
    
    const o = {
      foo: () => console.log("window", toString.call(this)),
          
      bar() {
        const baz = () => console.log("o", toString.call(this));
        baz();
      }
    }
    
    o.foo() // logs window [object Window]
    o.bar() // logs o [object Object]

    除了全球范围之外( Window 在浏览器中)只有函数才能在Javascript中形成作用域(和 {} ES2015中的块)。当 o.foo 调用arrow函数时,周围没有 baz 可以继承其 . 因此,它捕获了 绑定到的全局范围的绑定 对象

    什么时候 巴兹 由调用 o.bar ,箭头函数由 o、 巴 ( o、 巴 形成其父词法范围)并可以继承 o、 巴 结合 o、 巴 已调用 o 因此 一定会 o .

        3
  •  7
  •   Xin    8 年前

    希望这个代码展示能给你更清楚的想法。基本上,箭头函数中的“this”是“this”的当前上下文版本。请参见代码:

    // 'this' in normal function & arrow function
    var this1 = {
        number: 123,
        logFunction: function () { console.log(this); },
        logArrow: () => console.log(this)
    };
    this1.logFunction(); // Object { number: 123}
    this1.logArrow(); // Window 
    
        4
  •  2
  •   Alireza    7 年前

    箭头功能 this 指向Es6中的周围父级,意味着它的作用域与ES5中的匿名函数不同。。。

    这是一种非常有用的方法,可以避免将var self分配给ES5中广泛使用的var self。。。

    查看以下示例,在对象内指定函数:

    var checkThis = {
      normalFunction: function () { console.log(this); },
      arrowFunction: () => console.log(this)
    };
    
    checkThis.normalFunction(); //Object {}
    checkThis.arrowFunction(); //Window {external: Object, chrome: Object, document: document, tmpDebug: "", j: 0…}
    
        5
  •  1
  •   Plasmatium    7 年前

    你可以按照下面的方法来理解它

    // whatever here it is, function or fat arrow or literally object declare
    // in short, a pair of curly braces should be appeared here, eg:
    function f() {
      // the 'this' here is the 'this' in fat arrow function below, they are
      // bind together right here
      // if 'this' is meaningful here, eg. this === awesomeObject is true
      console.log(this) // [object awesomeObject]
      let a = (...param) => {
        // 'this is meaningful here too.
        console.log(this) // [object awesomeObject]
    }
    

    因此,fat arrow函数中的“this”未绑定,意味着您不能在此处将任何内容绑定到“this”。应用不会。呼叫不会。bind不会。 在文本编辑器中写下代码文本时,fat arrow函数中的“this”将被绑定 . '这个“in-fat-arrow”函数在这里有字面意义。您在文本编辑器中编写的代码是您的应用程序在repl中运行的代码。 除非您在文本编辑器中更改,否则fat arror中的“this”绑定永远不会更改 . 对不起,我的台球英语。。。

        6
  •  0
  •   Hamit YILDIRIM    5 年前

    在另一个示例中,如果单击下面的年龄按钮

    <script>
    var person = {
        firstName: 'John',
        surname: 'Jones',
        dob: new Date('1990-01-01'),
        isMarried: false,
        age: function() {
            return new Date().getFullYear() - this.dob.getFullYear();
        }
    };
    
    var person2 = {
        firstName: 'John',
        surname: 'Jones',
        dob: new Date('1990-01-01'),
        isMarried: false,
        age: () => {
            return new Date().getFullYear() - this.dob.getFullYear();
        }
    };
    
    </script>
    
    
    
    <input type=button onClick="alert(person2.age());" value="Age">
    

    它将引发如下异常

    JavaScript错误:未捕获类型错误:无法读取属性 第18行未定义的“getFullYear”

    但是如果你换了人,这条线

    return new Date().getFullYear() - this.dob.getFullYear(); 
    

    return new Date().getFullYear() - person2.dob.getFullYear();
    

    它将起作用,因为person2中的此范围已更改

        7
  •  0
  •   TrickOrTreat    5 年前

    箭头函数从不与绑定 this 关键字

    var env = "globalOutside";
    var checkThis = {env: "insideNewObject", arrowFunc: () => {
    console.log("environment: ", this.env);
    } }
    
    checkThis.arrowFunc()   // expected answer is environment: globalOutside
    
    // Now General function 
    var env = "globalOutside";
    var checkThis = {env: "insideNewObject", generalFunc: function() {
    console.log("environment: ", this.env);
    } }
    checkThis.generalFunc() // expected answer is enviroment: insideNewObject
    
    // Hence proving that arrow function never binds with 'this'
    
        8
  •  0
  •   LSSJ Λlpha    4 年前

    在箭头函数中使用时,将始终引用全局对象。使用常规函数声明引用本地对象。此外,您还可以使用对象名称作为上下文(object.method,而不是this.method),使其引用本地对象,而不是全局对象(窗口)。

        9
  •  0
  •   Ben.S    3 年前

    箭头函数与常规函数的区别:(取自 w3schools )

    对于arrow函数,此函数没有绑定。

    在常规函数中,this关键字表示调用函数的对象,可以是窗口、文档、按钮或其他任何对象。

    对于箭头函数,this关键字始终表示定义箭头函数的对象。

    // Regular Function:
    hello = function() {
      document.getElementById("demo").innerHTML += this;
    }
    
    // The window object calls the function:
    window.addEventListener("load", hello);
    
    // A button object calls the function:
    document.getElementById("btn").addEventListener("click", hello);
    
    // -------------------------------------------
    
    // Arrow function
    hello2 = () => {
      document.getElementById("demo2").innerHTML += this;
    }
    
    // The window object calls the function:
    window.addEventListener("load", hello2);
    
    // A button object calls the function:
    document.getElementById("btn2").addEventListener("click", hello2);
    <p><i>With a regular function this represents the <b>object that calls the function</b>:</i></p>
    
    <button id='btn'>click me regular function</button>
    
    <p id="demo">Regular function: </p>
    
    <hr>
    
    <p><i>With arrow function this represents the <b>owner of the function(=the window object)</b>:</i></p>
    
    <button id='btn2'>click me arrow function</button>
    
    <p id="demo2">Arrow function: </p>
        10
  •  0
  •   Manohar Reddy Poreddy    2 年前

    相关问题:

    来自- Why can't I access `this` within an arrow function?

    我们从这里了解到: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    没有自己对此的绑定 或super,不应用作方法。

    箭头函数根据 箭头函数的定义范围 .

    有问题 this 使用arrow函数,因此创建了一个类(可以是函数),并在arrow函数中访问了类变量,从而实现了使用arrow函数而不需要 function 关键词:

    class MyClassOrFunction {
        values = [];
        size = () => this.values.length;
        isEmpty = () => this.size() === 0;
    }
    
    let obj = new MyClassOrFunction();
    obj.size(); // function call here
    

    你也可以有这样一个getter,它没有 作用 关键字,但由于 return 语句,还可以访问其他成员函数:

    class MyClassOrFunction {
        values = [];
        size = () => this.values.length;
        get length() {  return this.size();  }
    }
    let obj = new MyClassOrFunction();
    obj.length; // NOTE: no function call here