【问题标题】:javascript scope rules for functions using this identifier使用此标识符的函数的 javascript 范围规则
【发布时间】:2015-01-09 20:59:32
【问题描述】:

我编写了以下代码以探索 javascript 范围规则 对于使用 this 标识符的函数。我希望第二次调用 person.helloFunk() 打印名字“Marvin”和年龄“非常非常老”,因为我 在函数对象本身上创建了属性 navn 和 age ,但它没有。 相反,它重复相同的输出“你好,我是 zaphod,我 42 岁”。 那么为什么 this 指的是嵌入函数的对象而不是函数本身(也是一个对象)?

var sayHello = function() {
    return "Hello, I'm " + this.navn + " and I'm " + this.age + " years old.";
}
var person = {navn: 'zaphod', age: 42};
person.helloFunk = sayHello;
console.log(person.helloFunk());

sayHello.navn = 'Marvin';
sayHello.age = 'verry verry old';
console.log(person.helloFunk());
console.log(person.helloFunk.navn);
console.log(person.helloFunk.age);

【问题讨论】:

    标签: javascript scope


    【解决方案1】:

    您正在函数上设置成员而不是人员对象。 如果您设置人员对象的成员,则函数中的“this”将引用正确的数据。 person.navn = '马文' console.log(person.helloFunk()); //将打印出“你好,我是 Marvin,今年 42 岁。”

    【讨论】:

      【解决方案2】:

      简单的答案是"because that is the way JavaScript is supposed to work"this 是动态的并且相对于容器进行解析(global|window 如果没有其他容器,除非在严格模式下,在这种情况下是 undefined)。

      如果您想更改this 指向的内容,可以使用callapplybind

      // call and apply differ only in how you pass arguments
      // In this case, no arguments, so the invocation is the same
      person.helloFunk.call(sayHello);
      person.helloFunk.apply(sayHello);
      
      var boundHello = person.helloFunk.bind(sayHello);
      boundHello();
      

      【讨论】:

      • 我认为将函数 (sayHello) 作为上下文传递给 callapplybind 确实是一个坏主意,也是一个坏例子。它应该是函数用作this 的对象。
      • @Ziarno - 在这种情况下,它已经添加了必要的数据 - 毕竟函数 JavaScript 中的一个对象。 sayHello instanceof Object === true
      【解决方案3】:

      this 并不指向函数本身,而是指向调用它的对象。

      function sayHello() {
        return this.hello;
      }
      
      sayHello.hello = "hi!";
      
      console.log(sayHello()); //undefined
      

      当您尝试运行此代码时:

      var sayHello = function() {
          return "Hello, I'm " + this.navn + " and I'm " + this.age + " years old.";
      }
      
      sayHello.navn = 'Marvin';
      sayHello.age = 'verry verry old';
      
      var person = {navn: 'zaphod', age: 42};
      person.helloFunk = sayHello;
      console.log(person.helloFunk());
      

      this 指的是person,而不是sayHello

      【讨论】:

        猜你喜欢
        • 2012-07-26
        • 1970-01-01
        • 2013-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多