对象。create在一些浏览器上还不是标准的,比如IE8, Opera v11.5, Konq 4.3都没有。你可以使用Douglas Crockford的Object版本。为这些浏览器创建,但这不包括在CMS的回答中使用的第二个“初始化对象”参数。
对于跨浏览器代码,同时进行对象初始化的一种方法是自定义Crockford的object .create。这里有一个方法:-
Object.build = function(o) {
var initArgs = Array.prototype.slice.call(arguments,1)
function F() {
if((typeof o.init === 'function') && initArgs.length) {
o.init.apply(this,initArgs)
}
}
F.prototype = o
return new F()
}
这维护了Crockford原型继承,也检查对象中的任何init方法,然后用参数运行它,比如说new man('John','Smith')。然后你的代码变成:-
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.build(userB, 'Bob'); // Different from your code
bob.sayHello();
所以bob继承了sayHello方法,现在拥有自己的属性id=1和name=' bob '。当然,这些属性既可写又可枚举。这也是一种比ECMA Object简单得多的初始化方法。创建,特别是当您不关心可写、可枚举和可配置属性时。
对于没有init方法的初始化,可以使用以下Crockford mod
Object.gen = function(o) {
var makeArgs = arguments
function F() {
var prop, i=1, arg, val
for(prop in o) {
if(!o.hasOwnProperty(prop)) continue
val = o[prop]
arg = makeArgs[i++]
if(typeof arg === 'undefined') break
this[prop] = arg
}
}
F.prototype = o
return new F()
}
这将使用Object填充userB自己的属性,按照它们定义的顺序。在userB参数之后从左到右生成参数。它使用for(prop in o)循环,因此,根据ECMA标准,属性枚举的顺序不能保证与属性定义的顺序相同。然而,在(4)主要浏览器上测试的几个代码示例显示,如果使用hasOwnProperty过滤器,它们是相同的,有时甚至不使用。
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}; // For example
var userB = {
name: null,
id: null,
sayHello: function() {
console.log('Hello '+ this.name);
}
}
var bob = Object.gen(userB, 'Bob', MY_GLOBAL.nextId());
我想说的是比Object简单一些。因为userB不需要init方法。此外,userB并不是特定的构造函数,但看起来像一个普通的单例对象。因此,使用这个方法,你可以从普通的普通对象构造和初始化。