Kar*_*ngh 7 javascript variable-declaration
这些有什么区别?
var a = 13;
this.b = 21;
document.write(a);
document.write(b);
Run Code Online (Sandbox Code Playgroud)
CMS*_*CMS 17
对于全局代码(不属于任何函数的代码),它们几乎是等效的,最后都在全局对象上创建属性.
不同之处在于a,已经使用var语句声明,变量实例化过程将使用全局对象作为变量对象 (1),并且它将该属性定义为不可删除,例如:
var a = 13;
delete a; // false
typeof a; // "number"
Run Code Online (Sandbox Code Playgroud)
然后,b由于this全局代码中的值(指向全局对象本身)也将是全局属性,但是可以删除此属性:
this.b = 21;
delete b; // true
typeof b; // "undefined"
Run Code Online (Sandbox Code Playgroud)
不要尝试Firebug中的第一个片段,因为Firebug的控制台在内部运行代码eval,并且在此执行上下文中,变量实例化过程的行为有所不同,您可以在此处尝试.
(1)变量对象(VO)是变量实例化过程用来定义FunctionDeclarations的标识符,用var语句声明的标识符和函数形式参数的标识符的对象,在不同的执行上下文中,所有这些标识符都是作为VO的属性绑定,Scope链由VO列表组成.
对于全局代码,VO本身就是全局对象,这就是为什么a最终成为它的属性.对于功能代码,VO(也称为FunctionCode 的激活对象)是在调用函数时在幕后创建的新对象,这就是创建新词法范围的原因,简而言之,我将讨论函数.
双方a并this.b可以解决的简单,只需通过a,并b因为在作用域链的第一个对象,又是全局对象.
此外,我认为工作知道变量实例化过程发生在代码执行之前,例如:
alert(a); // undefined, it exists but has no value assigned to it yet
alert(b); // ReferenceError is thrown
var a = 13;
this.b = 21;
Run Code Online (Sandbox Code Playgroud)
这些差异可能微不足道,但我认为值得了解.
现在,如果您发布的代码片段在函数内,则完全不同.
在您的示例中a使用var语句声明的标识符将是一个局部变量,仅可用于函数的词法范围(以及任何嵌套函数).
请记住,在JavaScript块中没有引入新的作用域,只有函数可以做,并且要在该作用域中声明变量,您应该始终使用var.
该this.b标识符将成为绑定到由该被称为所述对象的属性this的值,但... 什么是this??? .
this调用函数时,JavaScript中的值是隐式设置的,它取决于您如何调用它:
当您使用new运算符时,this函数内部的值将指向新创建的对象,例如:
function Test() {
this.foo = "bar";
}
var obj = new Test(); // a new object with a `foo` property
Run Code Online (Sandbox Code Playgroud)当您调用作为对象成员的函数时,该this函数内的值将指向基础对象,例如:
var obj = {
foo: function () {
return this == obj;
}
};
obj.foo(); // true
Run Code Online (Sandbox Code Playgroud)当您调用没有任何基础对象的函数时,该this值将引用全局对象:
function test() {
return this == window;
}
test(); // true
Run Code Online (Sandbox Code Playgroud)this使用call或调用函数时,可以显式设置该值apply:
function test() {
alert(this);
}
test.call("hello world!"); // alerts "hello world!"
Run Code Online (Sandbox Code Playgroud)