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

发布于 2024-09-10 05:38:01 字数 653 浏览 4 评论 0原文

我已经开始编写我的“类”类型 JavaScript 函数,例如模块模式或揭示模块模式。这避免了使用“new”,并允许我在一个地方定义哪些函数是公共的。但是,我一直无法了解如何以这种模式使用和访问公共数据成员。

例如,下面的成员“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;}
    }
}

有没有办法让 myobj.id 返回在initialize() 中设置的值?

I have begun writing my 'class' type JavaScript functions like the Module Pattern or Revealing Module patten. This avoids the use of 'new' and allows me to define which functions are public in a single place. However, I have been unable to see how to use and access public data members in this pattern.

e.g. the member 'id' below is accessible through myobj.getId(), but myobj.id is undefined.

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;}
    }
}

Is there no way to get myobj.id to work returning the value that was set in initialize()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我入戏太深 2024-09-17 05:38:01

你的问题是你没有利用关闭的优势。 id:id 行创建一个新变量作为您要返回的对象文字的成员。它具有默认值未定义。然后,您再次将相同的变量 id 分配回其自身,undefined

此外,模块是单个对象实例,而不是工厂函数。尝试这样的事情:

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 中生成一个对象实例。最多只能创建一个,这是模块的定义。然而,可以采用类似的方法来创建工厂函数。

Your problem is that you aren't taking advantage of closure. The line id:id creates a new variable as a member of the object literal you are returning. This has the default value undefined. Then you are assigning the same variable id back to itself, undefined again.

Also, a module is a single object instance, not a factory function. Try something like this:

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
});

The core of the module pattern is a self executing anonymous function that declares variables and then returns an object that has privileged access to those variables through closure.

The extra parens at the end, here containing an object literal with some options that get passed in, executes the function, which then returns an object and assigns it to myModule.

Anything declared as a member of that returned object can be accessed publicly. Code in the returned object has access to the variables defined in the anonymous function through closure even after the function has returned. The variables declared in the anonymous function are effectively private. Code outside the function cannot address them except through the methods provided in the returned object.

The whole thing results in a single object instance in myObject. No more than one can be created, which is the definition of a module. A similar approach could be taken the create a factory function however.

各自安好 2024-09-17 05:38:01

原因是您的变量 id 默认设置为 undefined,并且它的类型也将是 undefined。现在,因为未定义类型是一种原始类型,所以返回对象中的赋值将是一个值赋值,而不是引用。因此,obj.id 在实例中将变为 undefined,并且与构造函数中的 id 变量不同。

现在 initialize 将更改构造函数中的 id,而 getId 将返回相同的 id,但是 obj.id 将引用 undefined 对象属性。

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; }
    }
}

运行整个内容以查看其按预期工作。

The reason is that your variable id is set to undefined by default and it's type will be undefined as well. Now, because undefined type is a primitive one your assignment in the returned object will be a value assignment, not reference. So obj.id will become undefined in the instance and not the same as the id variable in the constructor function.

Now initialize will change the id in the constructor function, and getId will return the same id, but obj.id will refer to the undefined object property.

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 the whole stuff to see it works as expected.

雨落星ぅ辰 2024-09-17 05:38:01

您可以通过返回缓存对象而不是匿名对象来解决此问题,并仍然保留 Revealing 模块模式的语法糖。

例如:

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;
}());

You can solve this and still maintain the syntactic sugar of the Revealing module pattern by returning a cached object instead of an anonymous one.

eg:

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;
}());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文