我正在做一些Javascript R& D,虽然我读过 Javascript:The Definitive Guide 和 Javascript面向对象编程,但我还是有未成年人将问题从基于类的OOP转移到基于对象的基于OOP的词汇中。
我喜欢模块。命名空间,子类和接口。 w00t。这是我正在玩的东西:
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因为它已经存在(或实例化或者dunno这个术语的“正确”术语)而无法接受,并且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。
谢谢:)
答案 0 :(得分:5)
您声明了一个全局变量。声明后,可以在代码中的任何位置使用它。无论您向_name
请求(更密切window._name
),您每次都会收到全球信息。在你的情况下,在每个函数中替换了_name。最后一个功能是House,并且已经设置为“My House”
声明“私人”(本地)变量必须使用 var
声明。
检查出来:
var foo = function( a ) {
_bar = a;
this.showBar = function() {
console.log( _bar );
}
};
var a = new foo(4); // _bar ( ie window._bar) is set to 4
a.showBar(); //4
var b = new foo(1); // _bar is set to 1
a.showBar(); //1
b.showBar(); //1
_bar = 5; // window._bar = 5;
a.showBar();// 5
应该是:
var foo = function( a ) {
var _bar = a;
// _bar is now visibled only from both that function
// and functions that will create or delegate from this function,
this.showBar = function() {
console.log( _bar );
};
this.setBar = function( val ) {
_bar = val;
};
this.delegateShowBar = function() {
return function( ) {
console.log( _bar );
}
}
};
foo.prototype.whatever = function( ){
//Remember - here don't have access to _bar
};
var a = new foo(4);
a.showBar(); //4
_bar // ReferenceError: _bar is not defined :)
var b = new foo(1);
a.showBar(); //4
b.showBar(); //1
delegatedShowBar = a.delegateShowBar();
a.setBar(6);
a.showBar();//6
delegatedShowBar(); // 6
答案 1 :(得分:1)
如果删除关键字“this”,则_name位于“Globe”范围内。
查看您的代码。
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
最后,房子将覆盖地球范围内的“_name”值,名称为“My House”。