小编典典

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

all

我刚刚在 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
}

阅读 65

收藏
2022-05-23

共1个答案

小编典典

从我的另一篇文章中蚕食,这里比你想知道的还要

在开始之前,请记住关于 Javascript 的最重要的事情,并在没有意义时对自己重复一遍。Javascript
没有类(ES6classES2015 (ES6) class 语法有什么好处?)。如果某些东西看起来像一个类,这是一个聪明的把戏。Javascript
对象函数 。(这不是 100% 准确,函数只是对象,但有时将它们视为独立的事物会有所帮助)

this 变量附加到函数。每当你调用一个函数时, 都会被赋予一个特定的值,这取决于你调用函数的方式。这通常称为调用模式。

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

作为一种方法

方法是附加到对象的函数

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

当作为方法调用时, this 将绑定到函数/方法所属的对象。在此示例中,这将绑定到 foo。

作为一个函数

如果你有一个独立的函数, this 变量将绑定到“全局”对象,几乎总是浏览器上下文中的 窗口 对象。

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

这可能是让你绊倒的原因
,但不要难过。许多人认为这是一个糟糕的设计决定。由于回调是作为函数而不是作为方法调用的,这就是为什么您会看到看似不一致的行为。

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

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

您定义一个 指向 this 变量。闭包(它自己的一个主题)保留 了它 ,所以如果你调用 bar 作为回调,它仍然有一个引用。

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

作为构造函数

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

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

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

当作为构造函数调用时,将创建一个新对象,并将 this 绑定到该对象。同样,如果您有内部函数并且它们被用作回调,您将把它们作为函数调用,并且
this 将绑定到全局对象。使用那个 var that = 这个技巧/模式。

有些人认为constructor/new关键字是Java/传统OOP程序员用来创建类似于类的东西的一种方式。

使用 Apply 方法

最后,每个函数都有一个名为“apply”的方法(是的,函数是 Javascript 中的对象)。Apply 可以让你确定 this
的值是什么,还可以让你传入一个参数数组。这是一个无用的例子。

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