我正在尝试了解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 }
};
由于命名冲突(赋值不明确),我猜测在调用getMyVal0
后undefined
为init()
。
但是(在致电init()
后)为什么getMyVal1
会返回undefined
?对myVal1
的引用不应含糊不清。 Javascript是否需要明确使用this
? getMyVal2
会返回预期值,但同样,我很惊讶我需要明确的this
。
请澄清这种行为。
最终,我正在尝试在初始化成员变量时为函数参数建立命名约定。根据行业惯例,IRR是IRR,似乎this
应该允许我避免为变量添加两个名称(不总是用this
引用成员变量。)做什么的惯例是什么?想做什么?
答案 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"
顺便说一句,您可以将closure
和init
调用合并为一个函数:
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"