Javascript"私有"与实例属性

Phi*_*hix 4 javascript closures namespaces

我正在做一些Javascript研发,虽然我读过Javascript:The Definitive GuideJavascript面向对象编程,但我仍然遇到一些小问题,让我的基础出自基于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")
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

我试图找到模块化我的代码(并理解原型)并将所有内容分开的最佳方法.注意Globe是一个需要实例化的函数new,Umbrella是一个单例并且已经声明,Igloo使用了我今天在工作中想到的东西,并且看起来像我希望的那样工作,并且House是用于测试的另一个Iglooesque函数.

这个输出是:

Globe
unavailable
Igloo
My House
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.出于语法原因,必须在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")
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

并且this.name进入_name("私有"属性),它不起作用,而是输出:

My House
unavailable
My House
My House
Run Code Online (Sandbox Code Playgroud)

有人会善意解释这个吗?显然_name在每次迭代时都会被覆盖,而不是读取它附加的对象的属性.

这一切似乎有点太冗长需要this和有点奇怪的IMO.

谢谢 :)

abu*_*uba 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
Run Code Online (Sandbox Code Playgroud)

应该:

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
Run Code Online (Sandbox Code Playgroud)