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

What happens with "var" variables inside a JavaScript Constructor?

本文关键字:变量 什么 var 构造函数 JavaScript      更新时间:2023-09-26

example:

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.

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

你给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是一个string,一个number,或者一个boolean,即使你返回它,也不会给人们编辑权,甚至不会给予人们永久的查看访问权限 - 标量变量是按值传递的,所以你只是传递了当时的余额值 - 但是,如果平衡是一个object functionarray,他们将拥有永久访问权限来修改您内部工作的废话)

注意:必须在构造函数内部分配方法才能正常工作。原型无法访问内部变量。稍后添加方法不会授予他们访问内部变量的权限。

这意味着每个实例

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

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

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

function Foo() {
  this.bla = 1;
  var blabla = 10;
  this.getBlabla = function() {
    alert(blabla); // still here
  }
}

它将在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

js小提琴演示

用作构造函数的函数中用 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!

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

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

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

请参阅道格拉斯·克罗克福德的这篇文章。