【发布时间】:2012-02-08 16:05:09
【问题描述】:
我正在做一些 Javascript 研发工作,虽然我已经阅读了 Javascript:权威指南 和 Javascript 面向对象编程,但我仍然遇到一些小问题我从基于类的 OOP 转向基于词汇的、基于对象的 OOP。
我喜欢模块。命名空间、子类和接口。 w00吨。这是我正在玩的东西:
var Classes = {
_proto : {
whatAreYou : function(){
return this.name;
}
},
Globe : function(){
this.name = "Globe"
},
Umbrella : new function(){
this.name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
this.name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
this.name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
我试图找到将我的代码模块化(并了解原型设计)并将所有内容分开的最佳方法。注意Globe 是一个需要用new 实例化的函数,Umbrella 是一个单例并且已经声明,Igloo 使用了我今天在工作中想到的东西,并且似乎工作得和我想的一样好希望,House 是另一个用于测试的 Iglooesque 函数。
这个的输出是:
Globe
unavailable
Igloo
My House
到目前为止一切顺利。由于语法原因,必须在 Classes 对象之外声明 Globe 原型,Umbrella 不能接受,因为它已经存在(或实例化或......不知道这个“正确”术语),并且 Igloo 有一些闭包声明给你。
但是...
如果我将其更改为:
var Classes = {
_proto : {
whatAreYou : function(){
return _name;
}
},
Globe : function(){
_name = "Globe"
},
Umbrella : new function(){
_name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
_name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
_name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
并将this.name 变成_name(“私有”属性),它不起作用,而是输出:
My House
unavailable
My House
My House
有人好心解释一下吗?显然_name 在每次迭代时都会被覆盖,而不是读取它所附加的对象的属性。
这一切似乎有点过于冗长,需要this 和有点奇怪的 IMO。
谢谢:)
【问题讨论】:
-
因为你的“私人”是全球性的。
-
我最初有
var关键字,但错过了将其放回原处。这就是为什么您不在凌晨 3 点提问的原因;)无论如何,谢谢您的回答,它使现在更有意义了,同样的解决方案也适用。干杯! -
您可能对ES5 OO sugar感兴趣
-
我已经看到并使用了其中一些库,这些库允许更结构化的类 OOP 风格的使用,但我仍然需要了解该语言。不过谢谢,我一直在寻找好的库。
-
文章列出了原型的OO机制。不是肮脏的经典 OO 仿真。我个人最喜欢的是combining extend and Object.create
标签: javascript namespaces closures