构造函数和Object之间的区别

时间:2010-12-30 01:01:06

标签: javascript function object constructor

我肯定需要了解一下。

之间的区别是什么:

var MY_APP = function(){
    this.firstMethod = function(){
       //something
    };
    this.secondMethod = function(){
       //something
    };
};

var MY_APP = {
    firstKey: function(){
       //something
    },
    secondKey: function(){
       //something
    }
};

除了一个明显的事实,一个是一个函数,另一个是一个对象,代码流,原型,模式有什么不同......什么,什么时候我们应该使用第一个或者第二λ

我在这个区域如此分散,以至于我不确定我是否正确解释了疑问,但如果你问的话可以给出进一步的信息。

4 个答案:

答案 0 :(得分:5)

两者之间的关键区别在于如何使用它们。顾名思义,构造函数旨在创建和设置对象的多个实例。另一方面,对象文字是一次性,如字符串和数字文字,并且更常用作配置对象或全局单例(例如,用于命名空间)。

关于第一个要注意的例子,有一些细微之处:

  1. 执行代码时,会创建一个匿名函数并将其分配给MY_APP,但不会发生任何其他情况。在明确调用MY_APP之前,firstMethodsecondMethod不存在。
  2. 根据MY_APP的调用方式,方法firstMethodsecondMethod最终会出现在不同的地方:
    1. MY_APP():由于没有提供上下文,this默认为window,方法将变为全局。
    2. var app1 = new MY_APP():由于new关键字,会创建一个新对象并成为默认上下文。 this引用新对象,并将方法分配给新对象,随后将其分配给app1。但是,MY_APP.firstMethod仍未定义。
    3. MY_APP.call(YOUR_APP):这会调用我的MY_APP,但会将上下文设置为另一个对象YOUR_APP。这些方法将分配给YOUR_APP,覆盖YOUR_APP具有相同名称的任何属性。这是一个非常灵活的方法,允许在Javascript中进行多重继承或混合。
  3. 构造函数还允许另一级别的灵活性,因为函数提供闭包,而对象文字则不然。例如,firstMethodsecondMethod依赖于对象专用的公共变量password(无法在构造函数外部访问),这可以通过以下方式实现:

    var MY_APP = function(){
        var password = "GFHSFG";
    
        this.firstMethod = function(){
           // Do something with password
           alert(password); // Woops!
        };
        this.secondMethod = function(){
           // Do something else with password
        };
    };
    
    MY_APP();
    
    alert(password); // undefined
    alert(MY_APP.password); // undefined
    

答案 1 :(得分:2)

第一个是函数,第二个是对象文字。由于JS中的函数是第一类对象,因此函数可以在其上具有属性,就像任何其他对象一样。

通常情况下,如果你想创建一个你可能从经典继承语言中熟悉的“类”,你会做类似

的事情。
function MyClass() {...}

这里记录http://www.crockford.com/javascript/inheritance.html

要回答编辑中提出的问题,您可以在不同的情况下使用它们。对象文字用于传递配置。典型的使用模式是接受像这样的对象文字的方法

 something.init({
      length: 10,
      height: 10,
      text: 'some text'
 });

等等。

在创建命名空间时,您可以使用类似于第一个示例的内容。 Javascript有一些有趣的语言功能,你可以拥有以下形式的所谓“自我调用函数”:

var myApp = (function(){
    var firstMethod = function() {...}
    ...
})();
这里详细介绍了做类似事情的动机 http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/

您还可以通过自己喜欢的javascript调试控制台调查差异。在萤火虫和铬合金中,我做了以下事情:

  
    
      
        

var ol = {}; ol.prototype;

                 

var fn = function(){}; fn.prototype;

      
    
  

第一行打印undefined,第二行返回带有'function'构造函数的原型

答案 2 :(得分:2)

构造函数可以按原样重用,对象文字需要重复或包装在一个函数中才能重用。

在函数中包装对象文字的示例:

function MY_APP() {
  return {
    firstKey: function(){
       //something
    },
    secondKey: function(){
       //something
    }
  };
}

使用构造函数创建的对象将其构造函数属性设置为构造函数。但是,当您使用分配给变量而不是命名函数的匿名函数时,构造函数仍然是无名的。

除此之外,没有任何差异。两者都创建分配给对象属性的匿名函数,因此生成的对象是相同的。您可以将此进行比较,将命名函数分配给属性,或者使用原型函数,两者的区别在于每个函数只存在一次,而不是为每个对象反复创建。

答案 3 :(得分:1)

JavaScript中关于函数和对象之间的区别存在一些混淆。

在第一种情况下

  var MY_APP = function() { this.v = 7; ... }

  function MY_APP(x) { this.v = x; ... }

声明一个函数,一个对象。在MY_APP中,this指的是全局对象。
这意味着调用函数MY_APP(7)将全局赋值v为值7.(在您的情况下,函数firstMethod将全局声明。)

  MY_APP(3);  // The global variable v is set to 3
  MY_APP(4);  // The global variable v is overwritten and set to 4

要将MY_APP用作对象,需要对其进行实例化,例如

  var obj1 = new MY_APP(3);
  var obj2 = new MY_APP(4);

obj1.v设为3,obj2.v设为4.

请注意,您还可以使用prototype关键字(而不是this.firstMethod ...)添加方法

  MY_APP.prototype.firstMethod = function () { ... }

在第二种情况下

  var MY_APP = { ... };

创建一个对象一个对象,其名称为MY_APP。 this关键字引用该对象MY_APP。