我是一名拥有15年经验的java程序员,但我很难理解javascript。下面是一个例子,我很想了解两个定义之间的差异。
如果我想创建Subject的对象实例,这两个定义是非常不同还是可以接受?
var Subject1 = ( function( window, undefined ) {
function Subject1() {
this._list = [];
}
// this method will handle adding observers to the internal list
Subject1.prototype.observe = function observeObject( obj ) {
console.log( 'added new observer' );
this._list.push( obj );
};
Subject1.prototype.unobserve = function unobserveObject( obj ) {
for( var i = 0, len = this._list.length; i < len; i++ ) {
if( this._list[ i ] === obj ) {
this._list.splice( i, 1 );
console.log( 'removed existing observer' );
return true;
}
}
return false;
};
Subject1.prototype.notify = function notifyObservers() {
var args = Array.prototype.slice.call( arguments, 0 );
for( var i = 0, len = this._list.length; i < len; i++ ) {
this._list[ i ].update.apply( null, args );
}
};
return Subject1;
} )( window );
//Subject2 example but based on the revealing module design pattern.
function Subject2() {
this._list = [];
// this method will handle adding observers to the internal list
function observeObject( obj ) {
console.log( 'added new observer' );
this._list.push( obj );
}
function unobserveObject( obj ) {
for( var i = 0, len = this._list.length; i < len; i++ ) {
if( this._list[ i ] === obj ) {
this._list.splice( i, 1 );
console.log( 'removed existing observer' );
return true;
}
}
return false;
}
function notifyObservers() {
var args = Array.prototype.slice.call( arguments, 0 );
for( var i = 0, len = this._list.length; i < len; i++ ) {
this._list[ i ].update.apply( null, args );
}
}
return {
notifyObservers : notifyObservers,
unobserveObject : unobserveObject,
observeObject : observeObject
}
}
所以现在我们有了Subject1和Subject2的功能定义,如果我这样做会有什么重大差异
var subject1 = new Subject1();
var subject2 = new Subject2();
两个定义具有完全相同的功能并执行相同的操作,但我需要了解它们的主要区别是什么?
谢谢
答案 0 :(得分:0)
Subject1定义是在对象的原型链上定义函数,而Subject2定义只是为该对象定义函数。
实例化新对象时会出现差异。当您实例化一个新的Subject1对象时,您仍然只有一个内存中所有函数的实例,因为它们存在于Subject1的原型链中。但是,每次实例化Subject2对象时,您还要创建为Subject2定义的所有函数的新实例,因为它们是为Subject2的每个实例定义的。
答案 1 :(得分:0)
第一个片段提供(可以说是)更传统的面向对象方法。大 Subject1 函数的开头和结尾处的附加大括号表示在程序启动时会立即调用它。这个函数的作用是1)注册对象方法和2)返回小的 Subject1 函数,它是实际的构造函数。因此,当您执行新的Subject1(); 时,您实际上只是创建了列表 - 方法已经定义。
第二个片段在很多方面与第一个片段不同。它为每个新对象创建方法的新副本,因此使用此方法创建的对象占用更多内存。但作为交换,您可以获得更大的灵活性:您可以拥有私有变量(通过使用var声明它们而不是将它们附加到对象)。您可以拥有私有函数(您只是不返回它们)并以编程方式构造新函数。