17

例子:

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.

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

4

7 回答 7

11

您提供给的任何内部方法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;

(增加了一点兴趣——如果balance是 a string、 anumber或 a boolean,即使你返回它,也不会赋予人们编辑权限,甚至是永久查看权限——标量变量是按值传递的,所以你只是当时传递 balance 的值——但是,如果 balance 是 an object、 afunction或 an array,他们将有永久访问权限来修改你内部工作中的废话)

注意:必须在构造函数内部分配方法才能使其工作。原型无法访问内部变量。稍后添加方法不会让他们访问内部变量。

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

于 2012-08-14T15:30:14.843 回答
6

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

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

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

  this.getBlabla = function() {
    alert(blabla); // still here
  }
}
于 2012-08-14T15:29:12.673 回答
3

它将成为. _ 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 演示

于 2012-08-14T15:20:58.740 回答
2

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!
于 2012-08-14T15:21:42.000 回答
1

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

于 2012-08-14T15:21:00.017 回答
0

如果不使用 var 关键字,“blabla”将成为全局变量。在代码中的其他点,如果您还使用不带 var 的 blabla,它也将是全局的,您可能会意外更改 blabla 的其他实例并在代码中引入意外错误。“var” 将变量放在当前范围内,所以在上面的例子中,它只能被 Foo 访问。

于 2012-08-14T15:21:54.137 回答
-2

blabla几乎可以被认为是 的私人成员Foo

请参阅Douglas Crockford 的这篇文章。

于 2012-08-14T15:21:50.193 回答