简体   繁体   English

如何在EcmaScript 5中添加静态成员

[英]How to Add Static Members in EcmaScript 5

I want to add a static function to a class in EcmaScript 5 JavaScript. 我想向EcmaScript 5 JavaScript中的类添加静态函数。 My class definition looks as follows: 我的班级定义如下:

var Account = {};

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

And I would create a new instance like this: 我将创建一个新的实例,如下所示:

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

Now I want to add a static function to the Account class. 现在,我想向Account类添加一个静态函数。 If I had created the Account class using a constructor function and the prototype property like this: 如果我使用构造函数和prototype属性创建了Account类,如下所示:

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

...I could just do: ...我可以做:

Account.instances = {};

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

But since I am using Object.defineProperty and not the prototype property to add members, Account.instances and Account.createInstance would also be instantiated when calling Object.create and therefore be properties of the instance. 但是由于我使用的是Object.defineProperty而不是prototype属性来添加成员,因此在调用Object.create时也将实例化Account.instancesAccount.createInstance ,因此它们是实例的属性。

How do i add a static member to a class when using EcmaScript 5 style object creation? 使用EcmaScript 5样式对象创建时如何在类中添加静态成员?

For ES 5 if you want static methods: 对于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;  
}

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

You seem to have some different things mixed up. 您似乎混杂了一些不同的东西。 The prototype is going to be shared fallback properties. 原型将共享后备属性。 If you want to define a static (I assume by what you're doing you mean non-writable property?) you can use defineProperty in the constructor. 如果您想定义一个静态(我假设您所做的事是指不可写属性?),则可以在构造函数中使用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;

But since I am using Object.defineProperty and not the prototype property to add members, Account.instances and Account.createInstance would also be instantiated when calling Object.create and therefore be properties of the instance. 但是由于我使用的是Object.defineProperty而不是原型属性来添加成员,因此在调用Object.create时也将实例化Account.instances和Account.createInstance,因此它们是实例的属性。

Any static properties or methods declared on the source object will not be deemed properties of the instance - they will be read from the prototype. 在源对象上声明的任何静态属性或方法都不会被视为实例的属性-它们将从原型中读取。

    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

You can't. 你不能

My class definition looks as follows var Account = {}; 我的类定义如下所示var Account = {};

That's not a class (if we would call the classical model like that), but just a prototoype object . 那不是一个类(如果我们这样称呼经典模型),而只是一个原型对象 And as you only have that, you will need to use other variables for static members like an instances-cache or a create function: 而且,只有这样,您将需要为静态成员使用其他变量,例如instances-cache或create函数:

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

You could namespace them, of course: 您当然可以为它们命名空间:

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

...but that looks very close to the classical pattern, doesn't it? ...但是看起来非常接近经典模式,不是吗? The only difference would be that you had a create function on a namespace object instead of a constructor function as the namespace object. 唯一的区别是您在名称空间对象上具有create函数,而不是将构造函数用作名称空间对象。

You might also be interested in the question Object.create Prototype Chains , where I have discussed a full inheritance model working like that, with create and inherit methods that all "class objects" inherit from a base . 您可能还对Object.create Prototype Chains这个问题感兴趣,在这里我讨论了一个完全继承模型,该模型具有所有“类对象”都从base继承的createinherit方法。


Further answer on your question in the comments: 在评论中进一步回答您的问题:

Doesn't Object.create make the new operator obsolete in EcmaScript 5? Object.create不会使EcmaScript 5中的新运算符过时吗?

No. The new keyword does two things: Set up the prototype chain of the new instance, and apply the the constructor function. 号的new关键字做了两两件事:建立新实例的原型链,并应用的构造函数。 Object.create does only the first thing, so you can use it when you dont need a function (or dont want it to execute). Object.create仅做第一件事,因此在不需要功能(或不希望其执行)时可以使用它。

In your case, you have such a function, so the classical model wouldn't be wrong here as well. 就您而言,您具有这样的功能,因此经典模型在这里也不会出错。 See also Using "Object.create" instead of "new" . 另请参见使用“ Object.create”代替“ new”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM