JavaScript对象创建的最佳实践

5

我有以下的 JavaScript 代码:

            var MyObject = (function() {

                function Setup(args) {
                    this.prop1 = args.x;
                    this.prop2 = args.y
                    this.prop3 = this.prop1 + this.prop2;

                    this.Create = function() {
                        return 'a' + helperFunc();
                    }

                    function helperFunc() {
                        return this.prop3;
                    }
                }

                return {
                    init : function(args) {
                        var setup = new Setup(args);

                        setup.Create();
                    }
                }

            })();


            $(function() {

                MyObject.init(someArgs);

            });
  1. Is my approach to object construction a good practice?

  2. I am getting undefined in the helperFunc when trying to access this.prop3.

  3. I have also tried to assign this.prop1 + this.prop2 to a local variable and use a function to return this value like so:

            function Setup(args) {
                    var total;
    
                    this.prop1 = args.x;
                    this.prop2 = args.y
    
                    total = this.prop1 + this.prop2;
                    this.getTotal = function() {
                            return total;
                    };
    
                    this.prop3 = this.prop1 + this.prop2;
                    ...
    

当在helperFunc中像这样调用它:

                       return this.getTotal();

我遇到了一个问题:this.getTotal不是一个函数。

我一直在研究对象创建和使用闭包来模拟私有成员等内容,由于没有一种定义对象的标准方式,我感到很困惑。

说实话,我真的不理解这个结构:

                       var myObject = (function() { ... } ();

我经常在jQuery插件中看到它被使用,但是第一个括号后面跟着空括号的意思和作用是什么呢?欢迎提供任何相关知识。
此外,我已经订购了Douglas Crockford的JavaScript书籍,在它到达之前,我需要尝试解决这个问题。

1
https://dev59.com/Um865IYBdhLWcg3wOb9h - mplungjan
这里有很多问题。如果您尝试将每个问题限制为一个问题,那么提供准确和精确答案会更容易些。 - Paul Butcher
mplungjan - 这是理解函数调用末尾括号的完美链接。我只需要理解为什么在调用函数时调用属性会得到未定义... - Alan Alcock
4个回答

4

引用Xhalent的精彩文章(非常出色且清晰地写作)中他提到的:

那是因为“this”的值与创建对象时的“this”的值不同。

所以在你的情况下:

...
  var _this = this.prop3;
  function helperFunc() {
    return _this;
  }
...

可能实现所需的内容。


这就是为什么我得到undefined的答案。我希望我也能标记Paul Butcher的答案,因为那有助于理解问题。我已经阅读了Xhalent的文章,它们非常有用。将值设置为私有变量,我不知道我可以从helperFunc函数中访问它。我在C#上花费了太多时间,需要停止思考传统的oop。期待Douglas Crockford的书。谢谢所有回答的人... - Alan Alcock

1
如果您有一个使用this的函数,您必须确保调用上下文是正确的。例如,使用this.helperFunc()而不是仅使用helperFunc()(但您还需要设置这样的事情,以便定义this.helperFunc)。在您的示例中,helperFunc内this的指代对象与Create()中的不同。
您可以将其视为函数不是作为对象的成员定义,而是作为对象的成员调用
根据上下文,this可能会解析为三件事:
  1. 如果函数调用之前带有new关键字,则为新创建的对象。
  2. 当函数被调用时,点左侧的对象。
  3. 如果没有提供上述内容,则为全局对象(window)。
如果函数在没有对象的情况下被调用,例如在this.Create中对helperFunc的调用,this将绑定到全局对象(在浏览器中使用window)。
例如:
var o = {someVal:"hello"};
o.doSomething = function (){alert(this.someVal)};

调用o.doSomething()将显然弹出"hello"。

给定:

var o2  = {someVal:"world"};
o2.someFunc = o.doSomething;

调用o2.someFunc()将会弹出"world",而不是你期望的指向odoSomething成员的指针所应该弹出的"hello"。

假设:

var someFunc = o.doSomething
someVal = "sailor"

调用someFunc()将会弹出 "sailor"。

另一个令人困惑的点是在Setup()函数内直接使用this。当你使用new调用一个函数时,就像你所做的那样,this并不绑定到全局对象,而是绑定到一个新的Setup对象实例。

对于上面的例子,这意味着调用new o.doSomething()将会弹出 "undefined",因为为该调用创建的新对象没有 "someVal" 成员。


1

1
你的网站有很多水平滚动条,难以阅读。 - woens

0

您可以在此页面上找到Mike Koss关于JS中OOP的好教程。

我经常在jQuery插件中看到它,但是第一个用括号包裹的空括号代表什么意思?

第二组括号立即调用您在第一组括号中声明的函数。

您可以分别声明和执行它(允许多次执行):

var myFunction = function() { alert("boo"); }; // Declare & instanciate
myFunction(); // Invoke
myFunction(); // Invoke again

或者在一行中同时执行两个操作:

(function() { alert("boo"); })(); // Can only invoke now, the function is anonymous and not stored anywhere.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接