Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的函数定义。但实际的区别是什么?_Javascript - Fatal编程技术网

javascript中的函数定义。但实际的区别是什么?

javascript中的函数定义。但实际的区别是什么?,javascript,Javascript,我是一名拥有15年经验的java程序员,但我正努力学习javascript。下面是一个例子,我很想了解这两个定义之间的区别 如果我想创建Subject的对象实例,这两个定义是非常不同还是可以接受 var Subject1 = ( function( window, undefined ) { function Subject1() { this._list = []; } // this method will handle adding observers to the

我是一名拥有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定义只是为该对象定义函数

当您实例化一个新对象时,就会出现差异。当实例化一个新的Subject1对象时,内存中仍然只有其所有函数的一个实例,因为它们存在于Subject1的原型链上。但是,每次实例化Subject2对象时,都会创建为Subject2定义的所有函数的新实例,因为它们是为Subject2的每个实例定义的

第一个代码片段(可以说)提供了一种更传统的面向对象方法。大Subject1函数开头和结尾的附加大括号表示程序启动时将立即调用该函数。此函数的作用是1)注册对象方法,2)返回小的Subject1函数,它是实际的构造函数。所以当你做新主题1()您实际上只是在创建列表-方法已经定义


第二个片段与第一个片段在许多方面不同。它会为每个新对象创建一个新的方法副本,因此使用这种方法创建的对象会占用更多的内存。但作为交换,您可以获得更大的灵活性:您可以拥有私有变量(通过使用var声明它们,而不是将它们附加到对象)。您可以拥有私有函数(您只是不返回它们)并以编程方式构造新函数。

one制作每个实例的道具/方法,另一个是继承的道具/方法。你问的是揭示模块模式和基于JS构造函数/原型的解决方案之间的区别是什么?如果区别是什么,那么是的,我想我问的就是这个问题。@dandavis你想让OP猜哪个是哪个吗?;)我很确定你的
主题2
不起作用,因为你访问
列表的方式。如果您知道您将只拥有命名对象的一个实例,例如Subject1或Subject2,那么将函数定义为Subject2中定义的函数是否仍然被视为不正确?@juckky一般来说,如果您要为该对象创建大量实例,在原型上定义函数是一个好主意。不在对象原型上定义方法的一个用例是,如果要在要定义的方法中使用本地“私有”变量,您希望该变量对对象的每个实例都是唯一的。如果您只有一个实例,那么麻烦使用构造函数是没有意义的,只需使用对象文字即可。谢谢。来自java开发背景,封装和隐藏数据是游戏主题2的名称,这似乎更直观。
var subject1 = new Subject1();
var subject2 = new Subject2();