Javascript闭包,'this'关键字和变量名称空间

时间:2012-08-02 15:07:43

标签: javascript closures this naming

我正在尝试了解this关键字的工作原理。

这篇文章The this keyword陈述

“在JavaScript中,这总是指我们正在执行的函数的”所有者“,或者更确切地说,指的是函数是一种方法的对象。”

function someClosure() {
    var myVal0, myVal1, myVal2;

    init = function (myVal0, myVal1, myVal2) {

        myVal0 = myVal0;
        this.myVal1 = myVal1;
        this.myVal2 = myVal2;

    };

    getMyVal0 = function() { return myVal0 };
    getMyVal1 = function() { return myVal1 }
    getMyVal2 = function() { return this.myVal2 }
};

由于命名冲突(赋值不明确),我猜测在调用getMyVal0undefinedinit()

但是(在致电init()后)为什么getMyVal1会返回undefined?对myVal1的引用不应含糊不清。 Javascript是否需要明确使用thisgetMyVal2会返回预期值,但同样,我很惊讶我需要明确的this

请澄清这种行为。

最终,我正在尝试在初始化成员变量时为函数参数建立命名约定。根据行业惯例,IRR是IRR,似乎this应该允许我避免为变量添加两个名称(不总是用this引用成员变量。)做什么的惯例是什么?想做什么?

3 个答案:

答案 0 :(得分:3)

PPK在那篇文章中完全不正确。 this指针的值通过每个函数调用重新确定。 JavaScript中没有“方法所有权”这样的东西。作为对象属性引用的结果调用方法时,this指针获取值,这是真的,但同一方法可以是许多不同对象的属性。

除此之外,重要的是要理解构造函数中的局部变量与对象this所引用的对象属性完全不同。也就是说,

function Constructor() {
  var x, y;

  x = "whatever";
}

在该代码中,变量“x”和“y”是局部变量,而不是对象的属性。

答案 1 :(得分:3)

ECMAscript 2-6-2第3版以及ES5中的var关键字几乎只说“在当前上下文中声明该变量”。另一方面this总是引用“调用对象”(我喜欢称之为),这是一个不同的故事。

函数的context不能通过Javascript本身直接访问,它只存在于底层lexicalEnvironment(ES5)或Execution Context -> Activation Object(ES3)中。

因此,通过显式调用this.xxx,您正在读取和写入OOI(可以根据如何调用该方法进行更改)。 "Activation Object"成立

  • 形式参数
  • var
  • 声明的变量
  • 功能声明

所有这些内容都 存储在由this引用的对象中。

答案 2 :(得分:2)

在MDN阅读此introduction to the this keyword

this的值取决于您如何调用该函数。但是您根本不会调用init,并且所有变量仍为undefined

  

根据行业惯例,this应该允许我避免为变量添加两个名称

没有。 JavaScript中的this与Java等其他语言中的this不同。它不允许您从更高的范围访问变量。在您的情况下,init函数的参数只会遮蔽myClosure中的变量 - 您无法访问它们。如果需要,您需要重命名它们。使用此脚本:

var init, getMyVal; // global, or at least "outer", variables

function closure() {
    var myVal, myVal2; // scoped to the closure

    // all the following function can access them
    init = function(val, myVal2) {
        myVal = val; // assign the argument to the closure variable
        // myVal2 === myVal2 - sorry, this only refers to the argument
    };
    getMyVal = function() {
        return myVal; // get the closure variable
    };
};
closure(); // execute it - you might also have used a immediately-executing function

init("some value");

getMyVal(); // "some value"

顺便说一句,您可以将closureinit调用合并为一个函数:

var getMyVal;
function initClosure(myVal) {
    // the argument is scoped to this function, like a var declaration

    getMyVal = function() { return myVal; };
}
initClosure("some value");

getMyVal(); // "some value"