在Javascript中使用var和this有什么区别?

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 的激活对象)是在调用函数时在幕后创建的新对象,这就是创建新词法范围的原因,简而言之,我将讨论函数.

双方athis.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中的值是隐式设置的,它取决于您如何调用它:

  1. 当您使用new运算符时,this函数内部的值将指向新创建的对象,例如:

    function Test() {
      this.foo = "bar";
    }
    var obj = new Test(); // a new object with a `foo` property
    
    Run Code Online (Sandbox Code Playgroud)
  2. 当您调用作为对象成员的函数时,该this函数内的值将指向基础对象,例如:

    var obj = {
      foo: function () {
        return this == obj;
      }
    };
    obj.foo(); // true
    
    Run Code Online (Sandbox Code Playgroud)
  3. 当您调用没有任何基础对象的函数时,该this值将引用全局对象:

    function test() {
      return this == window;
    }
    test(); // true
    
    Run Code Online (Sandbox Code Playgroud)
  4. this使用call或调用函数时,可以显式设置该值apply:

    function test() {
      alert(this);
    }
    test.call("hello world!"); // alerts "hello world!"
    
    Run Code Online (Sandbox Code Playgroud)