我正在寻找在JS中拥有对象的最优化方法;因为JS允许你以多种方式做某事我想知道哪些被认为是“最佳实践”。
对象的概念用法是:
var John = new Person('John');
var Foo = new Person('Foo');
console.log(John.getName()); //Return 'John'
console.log(Foo.getName()); //Return 'Foo'
console.log(John.name); //undefined
console.log(Foo.name); //undefined
我在这里有一些例子:
示例#1:
var Person = function (name) {
this.getName = function () { return name; }
}
这里我实际上没有属性; “name”无法更改或由public读取,getName方法可以公开访问,并使用本地名称变量调用。这实际上满足了我的需求。
示例#2:
function Person (name) {
this.getName = function () { return name; }
}
这与示例#1具有相同的行为。从功能和性能的角度来看,我只是不确定var method = function () {};
和function method() {};
之间的区别。
示例#3:
var Person = function (name) {
this.name = name;
Person.prototype.getName = function () { return this.name; }
}
这里我有name属性,可以公开读/写,我也有一个可以公开访问的原型getName方法。
示例#4:
var Person = function (name) {
this.name = name;
if (!Person._prototyped) {
Person.prototype.getName = function () { return this.name; }
Person._prototyped = true;
}
}
这里我有我在示例#3中所拥有的,区别在于我确保原型方法只设置一次且仅在需要时。
所以最后一个问题是,你建议我遵循哪些或者其中哪一个是最佳做法?
答案 0 :(得分:3)
对于你想要的,最好的方法可能就是:
/**
* @constructor
*/
function Person(name) {
this.getName = function() {
return name;
};
}
这是为什么?好吧,首先,封装。如果可能,您通常希望将函数放在原型中,如下所示:
/**
* @constructor
*/
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
};
但是!在这种情况下,您似乎不希望Person.name
可访问。因此,您需要使用闭包。
至于这种方法:
var Person = function (name) {
this.name = name;
Person.prototype.getName = function () { return this.name; }
}
那不好。您公开公开this.name
,因此它没有优先于以前的原型方法,但您不断使用相同的函数覆盖Person.prototype.getName
。这样做是没有意义的; this
每次都是适当的对象。更重要的是,在第一个Person.prototype.getName
对象被实例化之前,Person
将无法访问,因此首先将其设置为“公共”没有太大意义。你的第四个例子基本相同,更难以理解,但它仍然具有所有的缺点。
所以,在这种情况下,请使用第一个版本;但是,尽可能在prototype
上设置方法,以便可以在实例外部调用它们。
最后,我建议使用:
function Person() {
}
在
var Person = function() {
}
因为1)第二个例子缺少一个分号,2)var
暗示构造函数是变量,它不应该是,3)我不相信JDoc允许@constructor
应用于它,导致Closure Compiler中的警告至少 1 。
1 好的,不是那么重要。但仍然......
答案 1 :(得分:2)
在示例3和4中,它应该是:
var Person = function (name) {
this.name = name;
};
Person.prototype.getName = function () { return this.name; }
和
var Person = function (name) {
this.name = name;
};
if (!Person._prototyped) {
Person.prototype.getName = function () { return this.name; }
Person._prototyped = true;
}
因为每次调用构造函数时都不需要弄乱原型。
不确定哪个最快(因为它们都适用于您的目的),这是您的要求,但我不担心,因为这似乎是微优化。如果您必须知道,那么您可以使用http://jsperf.com/
这样的网站我能想象的最快方式是:
function Person(name) {
this.getName = function() {
return name;
};
}
正如minitech所说。原因如下:
每次js引擎必须“向上”原型链时,它会消耗掉一小部分ms(或IE上的一小部分:)),并且因为声明变量会占用时间(也可以忽略不计)避免这样做。希望有所帮助
答案 2 :(得分:0)
在node.js上运行良好。 AFAIK,论证是可变的。闭包会记住价值观。因此,这将有效。我想这解决了这一切。
var Person = function(Name) {
this.getName = function(){return Name;}
this.setName = function(newName) { Name = newName; }
},
me = new Person('John');
console.log(me.getName());
me.setName('Peter');
console.log(me.getName());