代码之家  ›  专栏  ›  技术社区  ›  pc1oad1etter

当从JavaScript构造函数返回对象时(避免“new”),如何实现公共成员?

  •  2
  • pc1oad1etter  · 技术社区  · 16 年前

    e、 g.下面的成员“id”可以通过myobj.getId()访问,但myobj.id未定义。

    function setup(){
        var myobj = MyObject();
        myobj.initialize();
        alert(myobj.getId()); // returns 3, as expected
        alert(myobj.id); // returns undefined
    }
    function MyObject(){
        var id;
        function initialize(){
            //do some stuff that initializes data including...
            id = 3;
        }
        return{
            initialize:initialize,
            id:id,
            getId:function(){ return id;}
        }
    }
    

    3 回复  |  直到 16 年前
        1
  •  1
  •   gblazex    16 年前

    原因是你的变量 id undefined 默认情况下,其类型为 未定义 也。现在,因为未定义的类型是一个基本类型,所以返回对象中的赋值将是一个值赋值,而不是引用。所以呢 obj.id 未定义 在实例中,与 构造函数中的变量。

    现在 initialize 将改变 身份证件 在构造函数中,以及 getId 将返回相同的 ,但是 对象id 未定义 对象属性。

    function MyObject(){
        // initialize is used as a public function so
        // this will always refer to the current instance
        function initialize(){
            this.id = 3;
        }
        return {
            // no need to define id here it will 
            // report undefined on access by default
            initialize: initialize,
            getId:function(){ return this.id; }
        }
    }
    

    Run

        2
  •  3
  •   jasongetsdown    16 年前

    你的问题是你没有利用闭包。线路 id:id 创建一个新变量作为要返回的对象文本的成员。这是默认值 undefined id 回到自我, 再一次。

    此外,模块是单个对象实例,而不是工厂函数。尝试以下操作:

    var myModule = (function(opts) {
        var foo = opts.foo || 0,    //private variables with default values
            bar = opts.bar || 0,    // if none are passed in
    
            product = function() {      //private method
                return (foo * bar);
            };
    
        return {
            getFoo : function() {   //public methods
                return foo;
            },
            fooTimesBar : function() {
                return product();
            }
        }
    })({
        foo : 5,                    //options object
        bar : 7
    });
    

    模块模式的核心是一个自动执行的匿名函数,该函数声明变量,然后返回一个对象,该对象通过 关闭

    最后的额外参数,这里包含一个对象文本和一些传入的选项,执行函数,然后返回一个对象并将其分配给 myModule

    任何声明为返回对象成员的内容都可以公开访问。返回对象中的代码可以通过闭包访问匿名函数中定义的变量,即使在函数返回之后也是如此。匿名函数中声明的变量实际上是私有的。函数之外的代码不能对它们进行寻址,除非通过返回对象中提供的方法。

    整个过程会在 myObject . 只能创建一个,这是模块的定义。但是,创建工厂函数也可以采用类似的方法。

        3
  •  0
  •   Michael Wolthers    14 年前

    您可以通过返回一个缓存对象而不是匿名对象来解决这个问题,并且仍然保持暴露模块模式的语法糖分。

    NAMESPACE.Module = (function () {
    
        //All public members go on api
        var api = {}
        api.id = 3;
    
        //Private members
        var self,
            foo,
            bar;
    
    
        /**
            @public
        */
        api.init = function () {
            self = this;
            console.log(this); //NAMESPACE.Module
        }
    
    
        /**
            @private
        */
        function _privateFunction() {
            console.log(self); //NAMESPACE.Module
        }
    
        return api;
    }());
    
    推荐文章