面向对象的Javascript概念

时间:2013-01-30 10:29:03

标签: javascript oop

我最近开始尝试使用更多的javascript和稍微更多的OO编程风格。我正在努力抓住一些可能非常基本的概念,所以我想知道是否有人可以帮助我。

下面是我从Stack Overflow中提取的代码片段,我将其作为示例使用:

var Person = (function () {
             // private static
             var nextId = 1;

                // constructor
                var cls = function () {
                    // private
                    var id = nextId++;
                    var name = 'Unknown';

                    // public (this instance only)
                    this.get_id = function () { return id; };

                    this.get_name = function () { return name; };
                    this.set_name = function (value) {
                            if (typeof value != 'string')
                                    throw 'Name must be a string';
                            if (value.length < 2 || value.length > 20)
                                    throw 'Name must be 2-20 characters long.';
                            name = value;
                    };
                };

                // public static
                cls.get_nextId = function () {
                    return nextId;
                };

                // public (shared across instances)
                cls.prototype = {
                                announce: function () {
                                    alert('My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"\r\n' +
                                    'The next id will be ' + Person.get_nextId());
                                }
                };

                return cls;
        })();

我有几个与这段代码相关的问题:

1)圆括号的双组表示var Person =(function(){...})();

2)每次创建Person对象时,变量nextId是静态的并且没有重新创建?在javascript中是否存在某种对象缓存(如加载的类)?

3)如果我使用新的Person()创建它,那么Person对象实际上是一个cls对象,因为这是从函数返回的吗?

4)如果我以这种方式创建对象,那么将方法附加到原型是否有任何意义,因为我可以在cls对象中声明announce函数,并且无论如何所有实例都会拥有它?

5)在cls函数中,'this'实际指的是什么?它是一个新创建的对象,是从这个函数本身返回的行'return cls;'?

这些问题非常基本但是javascript中的OO对我来说真的很混乱!我通常以面向对象的方式编程,但在java中它似乎更有意义......

由于

1 个答案:

答案 0 :(得分:2)

  

1)圆括号的双组表示var Person =(function(){...})();

这是一个正在执行的功能。它使函数内的局部变量不会在全局范围内声明。

示例:

tmp = function() { CODE };
tmp()

......与...基本相同。

(function() { CODE })();

你只需要在函数周围额外(),否则会出现语法错误。

  

2)变量nextId是如何静态的,并且每次创建Person对象时都不会重新创建?在javascript中是否存在某种对象缓存(如加载的类)?

由于在函数作用域内创建了nextId(参见1),因此从代码访问时它始终是相同的变量。

  

3)如果我使用新的Person()创建它,那么Person对象实际上是一个cls对象,因为这是从函数返回的吗?

函数(参见1)返回在里面创建的cls。是的,Personcls实际上是相同的。

  

4)如果我以这种方式创建对象,那么将方法附加到原型是否有任何意义,因为我可以在cls对象中声明announce函数,并且无论如何所有实例都会拥有它?

不同之处在于原型在所有实例之间是共享,而在构造函数中添加它们基本上是副本。使用原型更快,内存效率更高。

  

5)在cls函数中,'this'实际指的是什么?它是一个新创建的对象,是从这个函数本身返回的行'return cls;'?

没有。致电new Person()时,您实际上正在呼叫new cls()。 New创建一个新对象并调用函数,并将this设置为该对象。因此this函数中的cls是您正在创建的实际对象实例。


顺便说一下。如果你真的想用JavaScript做一些OOP编程我建议使用JohnResig的优秀代码片段:http://ejohn.org/blog/simple-javascript-inheritance/