什么是类变量的Javascript等价物?

时间:2015-05-10 12:22:44

标签: javascript class instance instance-variables class-variables

编辑:感谢@Aadit M Shah确认。

function Apple () {}
Apple.someVar = null; // Class variable
Apple.prototype.someVar = null; // Instance variable

3 个答案:

答案 0 :(得分:3)

在基于类的语言(即Java)中,静态成员是使用特殊语法创建的,并且可以像使用它们本身的成员一样使用。

在JavaScript中,没有特殊的语法来表示静态属性。但是,您可以通过使用构造函数并向其添加属性来实现这种类似的行为。与所有其他函数一样,构造函数是对象,可以具有属性。

让我们看一个例子:

我们有Car的构造函数,Car的静态方法和"实例"汽车的(原型授权)方法。

// constructor
var Car = function () {};

// a static method
Car.isShiny = function () {
  return "bling bling";
};

// "instance" method added to the prototype
Car.prototype.setPrice = function (price) {
  this.price = price;
};

正如预期的那样,我们可以调用静态方法和"实例"方法

// calling a static method
Car.isShiny(); // "bling bling"

// creating an instance and calling a method
var ford = new Car();
ford.setPrice(5000);

调用"实例"方法静态地赢了工作。 同样,在实例上调用静态方法也不会起作用。

typeof Car.setPrice; // "undefined"
typeof ford.isShiny; // "undefined"

在实例上调用静态方法有一种解决方法。定义一个引用静态方法的原型方法。

Car.prototype.isShiny = Car.isShiny;
ford.isShiny(); // "bling bling"

然而,这需要我们需要注意的一点复杂性。如果在静态方法中使用关键字this,则将引用Car构造函数或ford实例,具体取决于谁是调用者。

可以使用静态和非静态调用的相同方法。在instanceof的帮助下,我们可以知道如何调用该方法。

// constructor
var Car = function (price) {
  this.price = price;
};

// a static method
Car.isShiny = function () {

  // this always works
  var msg = "bling bling";

  if (this instanceof Gadget) {
    // this only works if called non-statically
    msg += ", it costs $" + this.price + '!';
  }

  return msg;
};

// a normal method added to the prototype
  Car.prototype.isShiny = function () {
  return Car.isShiny.call(this);
};

// static call
Car.isShiny(); // "bling bling"

//non static call
var benz = new Car('9999.99');
benz.isShiny(); // "bling bling, it costs $9999.99!"

该示例说明了使用公共静态成员。在JavaScript中,您也可以实现私有静态成员。

参考:JavaScript Patterns book。

答案 1 :(得分:2)

JavaScript是一种函数式语言,并不直接支持经典编程语言的功能,但可以通过闭包的概念来实现。

在您提供的代码段中,Apple.someVar和Apple.prototype.someVar对于从Apple构造函数创建的所有对象都具有相同的值,即类似于类变量。

要实现实例变量的功能,请使用闭包。 您可以在线查看有关闭包的更多帮助,这里有参考http://javascript.crockford.com/private.html

我正在提供一个小代码段,以便明确。

.bitband (NOLOAD) :
SUBALIGN(0x02000000)
{
    KEEP(*(.bitband))
} > BITBAND

变量redApple和greenApple共享相同的属性'type',但每个变量都有自己的color属性。

答案 2 :(得分:0)

TL;博士

function Apple () {}
Apple.someVar = null; // property on the constructor - doesn't affect instances
Apple.prototype.someVar = null; // the default value of the `someVar` property on instances returned by the constructor when using the `new` keyword

这是一个更详细的例子,可以看到它的实际效果:

function Apple () {}

Apple.color = 'blue'; // this doesn't do what you think it does.

console.log('Apple.color:', Apple.color); // blue

console.log('---'); 

// basic instantiation of the apples
var goldenDelicious = new Apple();
var grannySmith = new Apple();
var fuji = new Apple();

console.log('goldenDelicious.color:', goldenDelicious.color); // undefined
console.log('grannySmith.color:', grannySmith.color); // undefined
console.log('fuji.color:', fuji.color); // undefined

console.log('---'); 

fuji.color = 'red';

Apple.prototype.color = 'green'; 
// overrides color properties of all apples that have not 
// had their color set - even those of instances already created
// This is because their value is the default, and we are 
// modifying that default.

console.log('goldenDelicious.color:', goldenDelicious.color); // green
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red

console.log('---'); 

// assign some actual colors

goldenDelicious.color = 'yellow';
grannySmith.color = 'green';
fuji.color = 'red';

console.log('goldenDelicious.color:', goldenDelicious.color); // yellow
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red

console.log('---'); 

Apple.prototype.color = 'orange'; // all new apples will default to orange

var honeyCrisp = new Apple();

console.log('goldenDelicious.color:', goldenDelicious.color); // yellow
console.log('grannySmith.color:', grannySmith.color); // green
console.log('fuji.color:', fuji.color); // red
console.log('honeyCrisp.color:', honeyCrisp.color); // orange