2012-01-12 85 views
4

我正在做一些JavaScript [R & d和,虽然我读过JavaScript权威指南的JavaScript面向对象的编程,我仍然有一些小问题得到我的课程基于面向对象的面向对象和基于对象的面向对象的面向对象方法。的Javascript“私”与实例属性

我喜欢模块。名称空间,子类和接口。 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是另一个函数的函数供测试用。

的这个输出是:

Globe 
unavailable 
Igloo 
My House 

到目前为止好。由于语法原因,Globe原型必须在Classes对象之外声明,由于它已经存在(或实例化或...不知道这个“正确”的术语),并且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。

谢谢:)

+2

,因为你的 “私人”,是全球性的。 – Raynos 2012-01-12 12:09:20

+0

我原本在那里有'var'关键字,但是错过了它。这就是为什么你不会在凌晨3点提问的原因;) 无论如何,感谢你的回应,现在它更有意义并适用相同的解决方案。干杯! – Phix 2012-01-12 17:39:35

+0

您可能感兴趣的[ES5 OO sugar](http://raynos.org/blog/17) – Raynos 2012-01-12 17:51:07

回答

5

您声明了一个全局变量。在声明之后,它可以在代码中的任何地方使用。无论您何时请求_name(更接近window._name),您将收到每次全球通。你的情况在每个函数中被替换为_name。最后一个功能是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

如果删除关键字“这”,那么_name是在“环球报”的范围。

看着你的代码。

var globe, umb, igloo, house; 

globe  = new Classes.Globe(); 
umb  = Classes.Umbrella; 
igloo  = new Classes.Igloo("Ice"); 
house  = new Classes.House(); 

最后,房子将覆盖全球范围内名为“我的房子”的“_name”值。