【问题标题】:this inside function这个内部函数
【发布时间】:2009-12-26 13:17:55
【问题描述】:

我的问题是:

function Foo()
{
   this.foo = "bar"; // <- What is "this" here?
}

据我所知,这取决于Foo 的使用方式,即作为构造函数还是函数。 this在不同的情况下可以是什么?

【问题讨论】:

    标签: javascript function this


    【解决方案1】:

    this 关键字是指函数所属的对象,如果函数不属于任何对象,则为 window 对象。

    用在OOP代码中,指函数所属的类/对象 例如:

    function foo() {
        this.value = 'Hello, world';
    
        this.bar = function() {
            alert(this.value);
        }
    }
    
    var inst = new foo();
    inst.bar();
    

    此提醒:Hello, world

    您可以使用apply()call() 函数来操作this 引用的对象。 (有时非常方便的功能)

    var bar1 = new function() {
        this.value = '#1';
    }
    var bar2 = new function() {
        this.value = '#2';
    }
    
    function foo() {
        alert(this.value);
    }
    
    foo.call(bar1); // Output: #1
    foo.apply(bar2, []); // Output: #2
    

    【讨论】:

    • 我也很好奇。他的解释有问题吗?
    • @Danben 的回答强调使用 new 关键字,它创建一个新对象(javascript原型方式)。没有它,就不会创建新对象,并且该函数将“驻留”(如果我可以这么说)它所属的对象,或者如果在浏览器中,则为全局窗口对象。
    • 如果你有 class Foo { function Bar() { console.log(this); } },在 new Foo().Bar() 中使用“this”应该导致 Foo,而不是 Bar。但是如果你使用“var x = new Foo.Bar()”,那么新的 Foo.Bar 对象将被创建并且“this”将引用 Bar。
    【解决方案2】:

    阅读 Douglas Crockford 对此事的看法,引用 A Survey of the JavaScript Programming Language 的内容:

    函数是一个对象。它可以像其他对象一样包含成员。这允许一个函数包含它自己的数据表。它还允许一个对象充当一个类,包含一个构造函数和一组相关的方法。

    函数可以是对象的成员。当函数是对象的成员时,它被称为方法。有一个特殊的变量,叫做 this,当对象的方法被调用时,它被设置为对象。

    例如,在表达式 foo.bar() 中,this 变量被设置为对象 foo,作为函数 bar 的一种额外参数。然后功能栏可以引用 this 来访问感兴趣的对象。

    在像 do.re.mi.fa() 这样的更深层次的表达式中,this 变量被设置为对象 do.re.mi,而不是对象 do。在一个简单的函数调用中,这被设置为全局对象(又名窗口),这不是很有用。正确的行为应该是保留 this 的当前值,尤其是在调用内部函数时。

    此外,“this”可能会根据您的函数的调用方式而改变,请阅读 apply functioncall function

    我建议您花时间在他的(免费)演示文稿中学习 JavaScript 最伟大的思想之一,链接自 here

    【讨论】:

    • Crawford 页面上指向 Yahoo URL 的链接都已损坏。我能找到的最有可能的替代方法是从以下位置开始的 4 视频序列:youtube.com/watch?v=v2ifWcnQs6M
    【解决方案3】:

    在 JavaScript 中,约定(这只是约定)是任何以大写字母开头的函数都将用作构造函数。然后,一个人会打电话

    var foo = new Foo()this 将引用即将被 foo 引用的新创建的对象。

    当然,没有什么能阻止您单独调用Foo(),在这种情况下,this 将引用调用函数的对象。为避免混淆,不建议这样做。

    【讨论】:

    • 很高兴您阐明了 new 关键字的用法,因为几乎没有普通用户熟悉基于 javascript 原型的对象的工作原理,这会造成太多混乱。
    【解决方案4】:

    这取决于该函数的使用方式,我们可以使用两种基本类型的函数

    1. 功能
    2. 作为对象的函数,使用 new 关键字

    会一一看到

    1.功能

    var example = function () {
      console.log(this);
    };
    
    example();
    
    Output : window
    

    这里的'this'关键字指向窗口对象。

    默认情况下,这应该始终是 window 对象,它指的是根 - 全局范围。所以当我们 console.log(this);从我们的函数中,因为它是由窗口调用的(只是刚刚调用),我们应该期望 this 值是我们的窗口对象:

    2.作为对象的函数

    var example = function () {
      console.log(this);
    };
    
    var obj = new example();
    
    Output : example {}
    

    这里的 'this' 关键字指向新创建的示例对象。

    【讨论】:

      【解决方案5】:

      在 JavaScript 中,一切都是对象,甚至是函数。当你在下面的代码中说this.foo

      function Foo()
      {
         this.foo = "bar"; // <- What is "this" here?
      }
      

      foo 成为Foo 对象的成员变量

      【讨论】:

      • 我可能有 function MyClass () { function MyMethod () { console.log(this); } } 并且该日志调用应该记录 MyClass,而不是 MyMethod。请注意,MyClass 和 MyMethod 都是函数,但如果设计不是故意的,没有人会调用 new MyClass.MyMethod()。
      • 扩展 Luka 的例子:如果 Foo() 不是某个自定义对象的成员函数,它会成为全局对象的成员函数(window 如果在 Web 浏览器中执行)在这种情况下 @ 987654326@ 仍将指向window,然后foo 将成为window 的成员变量。
      • 'window' 范围是这里的重点。非常好,@JustAMartin。
      【解决方案6】:

      在 NodeJS 中有一些有趣的行为:

      function foo() {
          this.name = 'bar' // <- What is "this" here?
      }
      
      foo() // <- TypeError: Cannot set property 'name' of undefined
      

      但是使用箭头函数:

      const bar = () => {
          this.name = 'foo'
          console.log(this)
      }
      
      bar() // <- { name: 'foo' }
      

      我一直觉得传统的函数字面量有自己的上下文,但没有箭头函数,这似乎与我的理解相矛盾。

      鉴于这种行为,OP 的代码将无法正常工作...

      【讨论】:

      • 因为普通函数和箭头函数的作用域不同。箭头函数有它的闭包上下文,而其他没有。
      猜你喜欢
      • 2017-09-07
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 2011-07-13
      相关资源
      最近更新 更多