我最近开始尝试使用更多的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中它似乎更有意义......
由于
答案 0 :(得分:2)
1)圆括号的双组表示var Person =(function(){...})();
这是一个正在执行的功能。它使函数内的局部变量不会在全局范围内声明。
示例:
tmp = function() { CODE };
tmp()
......与...基本相同。
(function() { CODE })();
你只需要在函数周围额外()
,否则会出现语法错误。
2)变量nextId是如何静态的,并且每次创建Person对象时都不会重新创建?在javascript中是否存在某种对象缓存(如加载的类)?
由于在函数作用域内创建了nextId(参见1),因此从代码访问时它始终是相同的变量。
3)如果我使用新的Person()创建它,那么Person对象实际上是一个cls对象,因为这是从函数返回的吗?
函数(参见1)返回在里面创建的cls
。是的,Person
和cls
实际上是相同的。
4)如果我以这种方式创建对象,那么将方法附加到原型是否有任何意义,因为我可以在cls对象中声明announce函数,并且无论如何所有实例都会拥有它?
不同之处在于原型在所有实例之间是共享,而在构造函数中添加它们基本上是副本。使用原型更快,内存效率更高。
5)在cls函数中,'this'实际指的是什么?它是一个新创建的对象,是从这个函数本身返回的行'return cls;'?
没有。致电new Person()
时,您实际上正在呼叫new cls()
。 New创建一个新对象并调用函数,并将this
设置为该对象。因此this
函数中的cls
是您正在创建的实际对象实例。