7

我想在 EcmaScript 5 JavaScript 中的类中添加一个静态函数。我的类定义如下所示:

var Account = {};

Object.defineProperty(Account, 'id', {
    value : null
});

我会像这样创建一个新实例:

var theAccount = Object.create(Account);
theAccount.id = 123456;

现在我想在Account类中添加一个静态函数。如果我Account使用构造函数和这样的prototype属性创建了类:

var Account = function () {
    this.id = null;
};

...我可以这样做:

Account.instances = {};

Account.createInstance = function () {
    var account = new Account();
    account.id = uuid.v4();
    Account.instances[account.id] = account;
    return account;
};

但是由于我使用Object.defineProperty而不是prototype属性来添加成员,Account.instances并且Account.createInstance在调用时也会被实例化Object.create,因此是实例的属性。

使用 EcmaScript 5 样式对象创建时如何向类添加静态成员?

4

4 回答 4

5

对于 ES 5,如果你想要静态方法:

// A static method; this method only 
// exists on the class and doesn't exist 
// on child objects
Person.sayName = function() {
    alert("I am a Person object ;)");  
};

// An instance method; 
// All Person objects will have this method
Person.prototype.setName = function(nameIn) {
    this.name = nameIn;  
}

见@https ://abdulapopoola.com/2013/03/30/static-and-instance-methods-in-javascript/

于 2017-03-29T11:42:14.580 回答
1

你似乎把一些不同的事情混在一起了。原型将是共享的后备属性。如果你想定义一个静态的(我假设你在做什么你的意思是不可写的属性?)你可以在构造函数中使用defineProperty。

function Account(){
  Object.defineProperty(this, 'id', {
    value: uuid.v4()
  });
  Account.instances[this.id] = this;
}

Account.instances = {};

Account.prototype.id = null;


var account = new Account;
于 2012-07-27T11:48:52.730 回答
1

但是由于我使用 Object.defineProperty 而不是原型属性来添加成员,所以 Account.instances 和 Account.createInstance 在调用 Object.create 时也会被实例化,因此是实例的属性。

在源对象上声明的任何静态属性或方法都不会被视为实例的属性 - 它们将从原型中读取。

    var obj = {};
    obj.static = function() { alert('hello'); }
    var instance = Object.create(obj);
    instance.ownProperty = 'hello';
    alert(!!instance.static); //true - it has .static
    alert(instance.hasOwnProperty('static')); //false - but it's not its own
    alert(instance.hasOwnProperty('ownProperty')); //true
于 2012-07-27T13:33:11.933 回答
1

你不能。

我的类定义如下var Account = {};

那不是一个类(如果我们这样称呼经典模型),而只是一个原型对象。因为你只有这个,你需要为静态成员使用其他变量,比如实例缓存或创建函数:

var Account = {...};
var instances = [];
function createAccount(){...}

当然,您可以命名它们:

var Account = {
    proto: {...},
    instances: [],
    instantiate: function create(){...}
};

...但这看起来非常接近经典模式,不是吗?唯一的区别是您create在命名空间对象上有一个函数,而不是作为命名空间对象的构造函数。

您可能还对Object.create Prototype Chains问题感兴趣,我在其中讨论了一个完整的继承模型,其中create所有inherit“类对象”都继承自base.


在评论中进一步回答您的问题:

Object.create 不会使 EcmaScript 5 中的 new 运算符过时吗?

不,new关键字做了两件事:设置新实例的原型链,并应用构造函数。Object.create只做第一件事,因此您可以在不需要函数(或不希望它执行)时使用它。

在您的情况下,您具有这样的功能,因此经典模型在这里也不会出错。另请参阅使用 "Object.create" 而不是 "new"

于 2012-07-27T13:33:29.233 回答