一尘不染

函数中的“ this”关键字如何工作?

javascript

我刚刚遇到了一个有趣的JavaScript情况。我有一个类,该类的方法使用对象文字表示法定义了多个对象。在这些对象内部,this正在使用指针。从程序的行为,我推断出this指针是指向在其上调用方法的类,而不是由文字创建的对象。

尽管这是我期望的工作方式,但这似乎是任意的。这是定义的行为吗?跨浏览器安全吗?是否有任何推理依据说明它超出了“规格说明”的范围(例如,这是某些更广泛的设计决策/理念的结果)吗?简化的代码示例:

// inside class definition, itself an object literal, we have this function:
onRender: function() {

    this.menuItems = this.menuItems.concat([
        {
            text: 'Group by Module',
            rptletdiv: this
        },
        {
            text: 'Group by Status',
            rptletdiv: this
        }]);
    // etc
}

阅读 291

收藏
2020-04-25

共1个答案

一尘不染

从我的另一篇文章拆解,这里有更多的比你想要知道这个。

在开始之前,请记住关于Javascript的最重要的内容,并在没有意义的情况下对自己重复一遍。Javascript没有类(ES6class是语法糖)。如果某个东西看起来像一堂课,那是一个聪明的把戏。Javascript具有
对象功能 。(这不是100%准确的,函数只是对象,但有时将它们视为独立的东西会有所帮助)

在 这个变量被附连到功能。当你调用一个函数,这个被赋予了一定的价值,这取决于你如何调用该函数。这通常称为调用模式。

有四种方法可以调用javascript中的函数。您可以将函数作为方法,函数, 构造函数以及apply调用。

作为一种方法

方法是附加到对象的函数

var foo = {};
foo.someMethod = function(){
    alert(this);
}

当作为一种方法被调用,这将被绑定到对象的功能/方法是的一部分。在此示例中,它将绑定到foo。

作为功​​能

如果您具有独立功能,则此变量将绑定到“全局”对象,几乎总是在浏览器上下文中的window对象。

 var foo = function(){
    alert(this);
 }
 foo();

这可能是使您绊倒的原因 ,但并不难过。许多人认为这是一个错误的设计决定。由于回调是作为函数而不是方法调用的,因此这就是为什么您看到的行为似乎不一致。

很多人通过做类似的事情来解决这个问题

var foo = {};
foo.someMethod = function (){
    var that=this;
    function bar(){
        alert(that);
    }
}

你定义一个变量 指向 这个 。闭包(它本身 就是 一个话题)可以解决这个问题,因此,如果您将bar作为回调调用,它仍然具有引用。

注意:在use strict模式下,如果用作功能,this则不绑定到全局。(是undefined)。

作为建设者

您还可以将函数作为构造函数调用。根据您正在使用的命名约定(TestObject),这也 可能是您正在做的事情,并且是您的绊脚石

您可以使用new关键字将函数作为构造函数调用。

function Foo(){
    this.confusing = 'hell yeah';
}
var myObject = new Foo();

当作为一个构造函数调用时,一个新的对象将被创建,并且 将被绑定到该对象。同样,如果你有内部函数,他们正在使用回调,你会被调用它们的功能,并且
将被绑定到全局对象。使用该变量=此技巧/模式。

有人认为,构造函数/ new关键字是Java /传统OOP程序员的骨干,可以用来创建类似于类的东西。

使用Apply方法

最后,每个函数都有一个名为“apply”的方法(是的,函数是Javascript中的对象)。应用可以让你决定的价值来决定这将是,也可以让你在参数数组传递。这是一个无用的示例。

function foo(a,b){
    alert(a);
    alert(b);
    alert(this);
}
var args = ['ah','be'];
foo.apply('omg',args);
2020-04-25