JavaScript构造函数中的“var”变量会发生什么?

时间:2012-08-14 15:19:20

标签: javascript constructor var

示例:

function Foo() {
    this.bla = 1;
    var blabla = 10;
    blablabla = 100;
    this.getBlabla = function () { 
        return blabla; // exposes blabla outside
    }
}

foo = new Foo();

原始问题:

我知道bla将被分配给Foo的每个实例。 blabla会发生什么?

新问题:

我现在明白了:

this.bla = 1;     // will become an attribute of every instance of FOO.
var blabla = 10;  // will become a local variable of Foo(**not** an attribute of every    instance of FOO), which could be accessed by any instance of FOO only if there's a method like "this.getBlabla".
blablabla = 100;  // will define a **new** (or change if exist) global(window) variable.

[问题:] 我理解正确吗?

7 个答案:

答案 0 :(得分:10)

您提供给this的任何内部方法 - 即:this.method = function () {}; 在您的Foo构造函数内部 时, 所有 将引用blahblah,这对Foo个对象的每个实例都是唯一的。

function Wallet () {
    var balance = 0;
    this.checkBalance = function () { return balance; };
    this.depositAmount = function (amount) { balance += amount; };
}


var wallet = new Wallet();
wallet.checkBalance();   // 0
wallet.depositAmount(3);
wallet.checkBalance();   // 3

但它完全不受钱包外的访问,除非你从特权功能将其归还给某人。

wallet.balance; // undefined;

(添加了一点兴趣 - 如果balancestringnumberboolean,即使您退回,也会赢得“{1}} t赋予人们编辑权限,甚至永久查看访问权限 - 标量变量按值传递,因此您只是在当时传递余额的值 - 但是,如果余额是一个object,一个functionarray,他们可以永久访问以修改您内部工作的废话。

注意:要在构造函数内部分配 HAVE 方法,以使其正常工作。 原型无法访问内部变量。 之后添加方法不会让他们访问内部变量。

这意味着每个实例将占用更多内存,因为每个实例都有自己的方法副本,并且拥有自己的变量副本。 但是,如果您正在做的事情需要私人数据,这将是获得私人数据的好方法。

答案 1 :(得分:5)

在您的示例中,blabla是一个局部变量,因此当构造函数结束时它将消失。

如果在构造函数内部声明了一个使用该变量的函数,那么该变量将成为该函数闭包的一部分,并且只要该函数存活(即通常与对象一样长):

function Foo() {
  this.bla = 1;
  var blabla = 10;

  this.getBlabla = function() {
    alert(blabla); // still here
  }
}

答案 2 :(得分:2)

它将成为Foo()中的本地(想到'私人')变量。这意味着您无法在Foo()之外访问它。

function Foo() {
  this.bla = 1; // this becomes an extension of Foo()
  var blabla = 10; // this becomes a "Local" (sort of like a 'private') variable
}

您可以使用Foo方法公开它(通过返回它)。

function Foo() {
    var blabla = 10; // local

    this.getBlabla = function () { 
        return blabla; // exposes blabla outside
    }
}

现在在Foo()之外:

var FooBar = new Foo();

var what_is_blabla = FooBar.getBlabla(); //what_is_blabla will be 10

jsFiddle demonstration

答案 3 :(得分:1)

该变量是构造函数的本地变量,并且不能在该范围之外访问(通过this或其他方式),除非它被闭包捕获。

答案 4 :(得分:1)

在用作构造函数的函数内用var声明的变量将像在任何函数内使用var声明的所有其他变量一样,仅在执行该函数期间可见(除非值已关闭)过度使用闭包)。

换句话说,blabla在函数外部实际上是不可见的:

var foo = new Foo();
console.log(foo.bla);     // 1
console.log(foo.blabla);  // throws NameError

通过定义关闭这些变量的函数,它们成为JavaScript对“私有”变量最接近的东西:

function Foo() {
    this.bla = 1;
    var private = 1;

    this.increment = function() {
        ++private;
    }

    this.getPrivateValue = function() {
        return private;
    }
}

foo = new Foo();
console.log(foo.bla);                // 1
foo.bla = 6;                         // legal
console.log(foo.bla);                // 6
console.log(foo.getPrivateValue());  // 1
// console.log(foo.private);         // would throw an error
foo.increment();                     // legal
console.log(foo.getPrivateValue());  // 2
// foo.getPrivateValue() = 5;        // syntax error. Still can't reassign to private no matter what you try!

答案 5 :(得分:0)

如果不使用var关键字,“blabla”将成为全局变量。在代码中的其他点,如果你也使用没有var的blabla,它也将是全局的,你可能会意外地更改blabla的其他实例并在代码中引入意外的错误。 “var”将变量放在当前范围内,因此在上面的情况下,它只能被Foo访问。

答案 6 :(得分:-2)

blabla几乎可以被视为Foo的私人成员。

请参阅道格拉斯克罗克福德的this文章。