静态对象/对象字面量
静态对象或对象字面量不需要使用new
运算符进行实例化,同时表现为单例模式。考虑以下示例:
代码:
var staticObject1 = {
a: 123,
b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);
输出:
Object a=123 b=456 Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats
需要注意的是,改变 staticObject2.b
也会影响到 staticObject1.b
。然而,这可能并不总是期望的效果。像 Dojo 这样的许多库提供了对象克隆方法,如果您想复制静态对象,则可以缓解这种情况。继续上面的例子,请考虑以下代码:
Code:
var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);
输出:
Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats
注意,
staticObject1
和
staticObject2
的成员值相同,而
staticObject3
不受这些其他对象的更改影响。
静态对象还可用于创建项目或库名称空间,而不是填充全局范围,并促进了兼容性。
在创建需要可移植性或互操作性的库时,这非常有用。这可以在流行的库中看到,例如Dojo、YUI和ExtJs,在这些库中,所有或大多数方法都被称为
dojo.examplMethod()
、
YUI().exampleMethod()
或
Ext.exampleMethod()
。
静态对象也可以被认为是类似于C/C++中结构体的松散类比。
类构造函数/实例化对象
JavaScript中的类基于原型继承,这是一个更复杂的主题,可以在
这里、
这里和
这里阅读有关内容。
与静态对象相反,这种对象创建方法提供了利用JavaScript闭包属性的私有作用域对象成员和方法的独特机会。请考虑以下私有类成员的示例:
代码:var SomeObject = function() {
var privateMember = "I am a private member";
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
};
var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();
输出:
undefined string
I am a private member I am a public member
注意,typeof o.privateMember
的值为"undefined"且无法在对象外部访问,但在对象内部可以访问。
私有方法也可以实现,但不像公有方法那么简单直接。问题在于私有方法中this
的值默认为window
,因此必须应用两种技术之一来确保this
指向我们正在处理的对象,即SomeObject
的实例。考虑以下示例:
代码:
var SomeObject = function() {
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(this.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod.call(this);
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
输出:
undefined function function
I am a public member
请注意,在 privateMethodWrapper()
中,使用 call
并传递 this
作为函数的上下文来执行 privatemethod
。这是可以接受的;然而,下面的技术更可取(在我的意见中),因为它简化了调用范围并产生相同的结果。前面的示例可以更改为以下内容:
代码:
var SomeObject = function() {
var self = this;
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(self.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod();
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
输出:
undefined function function
I am a public member
这个答案是我在博客中发布的一篇文章的基础,其中我提供了更多的例子。希望能帮到你 ;)
staticObject1.b
也会影响staticObject2.b
。” - Rani Kheir