简体   繁体   English

构造函数和Object之间的区别

[英]Difference between a constructor and an Object

I definitely need some light on this. 我肯定需要对此有所了解。

What's the diference between: 有什么区别:

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

and

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

besides the obvious fact that one is a Function and the other an Object , what are the differences in code flow, prototypes, patterns... whatever, and when should we use the first or the second? 除了一个明显的事实,一个是一个函数,另一个是一个对象 ,代码流,原型,模式有什么不同......什么,我们什么时候应该使用第一个或第二个?

I'm so spaced out in this area that i'm not sure if i'm correctly explaining the doubt, but further info can be given if you ask. 我在这个区域如此分散,以至于我不确定我是否正确地解释了疑问,但如果你问的话可以给出进一步的信息。

The key difference between the two is in how they are intended to be used. 两者之间的关键区别在于如何使用它们。 A constructor, as its name suggests, is designed to create and set up multiple instances of an object. 顾名思义,构造函数旨在创建和设置对象的多个实例 An object literal on the other hand is one-off , like string and number literals, and used more often as configuration objects or global singletons (eg for namespacing). 另一方面,对象文字是一次性的 ,如字符串和数字文字,并且更常用作配置对象或全局单例(例如,用于命名空间)。

There are a few subtleties about the first example to note: 关于第一个例子,有一些细微之处需要注意:

  1. When the code is executed, an anonymous function is created and assigned to MY_APP, but nothing else happens. 执行代码时,会创建一个匿名函数并将其分配给MY_APP,但不会发生任何其他情况。 firstMethod and secondMethod don't exist until MY_APP is explicitly called. 在显式调用MY_APP之前, firstMethodsecondMethod不存在。
  2. Depending on how MY_APP is called, the methods firstMethod and secondMethod will end up in different places: 根据MY_APP的调用方式, firstMethodsecondMethod方法将在不同的地方结束:
    1. MY_APP() : Since no context is supplied, the this defaults to window and the methods will become global. MY_APP() :由于没有提供上下文, this默认为window ,方法将变为全局。
    2. var app1 = new MY_APP() : Due to the new keyword, a new object is created and becomes the default context. var app1 = new MY_APP() :由于new关键字,会创建一个新对象并成为默认上下文。 this refers to the new object, and the methods will get assigned to the new object, which subsequently gets assigned to app1 . this引用新对象,并将方法分配给新对象,随后将其分配给app1 However, MY_APP.firstMethod remains undefined. 但是, MY_APP.firstMethod仍未定义。
    3. MY_APP.call(YOUR_APP) : This calls my MY_APP but sets the context to be another object, YOUR_APP . MY_APP.call(YOUR_APP) :这会调用我的MY_APP,但将上下文设置为另一个对象YOUR_APP The methods will get assigned to YOUR_APP , overriding any properties of YOUR_APP with the same names. 这些方法将分配给YOUR_APP ,覆盖具有相同名称的YOUR_APP任何属性。 This is a really flexible method that allows multiple inheritance or mixins in Javascript. 这是一个非常灵活的方法,允许在Javascript中进行多重继承或混合。

Constructors also allow another level of flexibility since functions provide closures, while object literals do not. 构造函数还允许另一级别的灵活性,因为函数提供闭包,而对象文字则不然。 If for example firstMethod and secondMethod rely on a common variable password that is private to the object (cannot be accessed outside the constructor), this can be achieved very simply by doing: 例如,如果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

The first is a function, the second is an object literal. 第一个是函数,第二个是对象文字。 Since Functions in JS are first class objects, a function can have properties on it, just like any other object can. 由于JS中的函数是第一类对象,因此函数可以在其上具有属性,就像任何其他对象一样。

Typically, if you want to create a "class" that you might be familiar with from classical inheritance languages, you would do something like 通常,如果您想创建一个您可能从经典继承语言中熟悉的“类”,您可以执行类似的操作

function MyClass() {...}

as is documented here http://www.crockford.com/javascript/inheritance.html 正如此处记录的那样http://www.crockford.com/javascript/inheritance.html

To answer the question posed in your edits, you would use them both in different situations. 要回答编辑中提出的问题,您可以在不同的情况下使用它们。 Object literals are used to pass configurations around. 对象文字用于传递配置。 A typical usage pattern would be a method that accepts an object literal like so 典型的使用模式是接受像这样的对象文字的方法

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

and so on. 等等。

You could use something similar to your first example when creating a namespace. 在创建命名空间时,您可以使用类似于第一个示例的内容。 Javascript has some interesting language features in that you can have so-called "self-invoking functions" that are of the form: Javascript有一些有趣的语言功能,你可以拥有以下形式的所谓“自我调用函数”:

var myApp = (function(){
    var firstMethod = function() {...}
    ...
})();

the motivations behind doing something like this are detailed here 这里详细介绍了做这样的事情的动机
http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/ http://sparecycles.wordpress.com/2008/06/29/advanced-javascript/

You can also investigate the differences via your favorite javascript debugging console. 您还可以通过自己喜欢的javascript调试控制台调查差异。 In firebug and chrome, I did the following: 在firebug和chrome中,我做了以下事情:

var ol = {}; var ol = {}; ol.prototype; ol.prototype;

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

the first line prints undefined, the second returns a prototype with a constructor of 'function' 第一行打印undefined,第二行返回带有'function'构造函数的原型

The constructor can be reused as is, the object literal would need to be repeated or wrapped in a function to be reused. 构造函数可以按原样重用,对象文字需要重复或包装在一个函数中才能重用。

Example of wrapping the object literal in a function: 在函数中包装对象文字的示例:

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

The object created using the constructor will have it's constructor property set to the constructor function. 使用构造函数创建的对象将其构造函数属性设置为构造函数。 However, as you used an anonymous function assigned to a variable instead of a named function, the constructor will still be nameless. 但是,当您使用分配给变量而不是命名函数的匿名函数时,构造函数仍然是无名的。

Other than that, there isn't really any differences. 除此之外,没有任何差异。 Both create anonymous functions that are assigned to the properties of the object, so the resulting objects are the same. 两者都创建分配给对象属性的匿名函数,因此生成的对象是相同的。 You can compare this to assigning named functions to the properties, or using prototype functions, both having the difference that each function only exists once instead of being created over and over for each object. 您可以将此进行比较,以将命名函数分配给属性,或使用原型函数,两者的区别在于每个函数仅存在一次,而不是为每个对象反复创建。

There is some confusion in JavaScript regarding the difference between a function and an object. JavaScript中关于函数和对象之间的区别存在一些混淆。

In the first case , 在第一种情况下

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

or 要么

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

a function is declared, not an object. 声明一个函数, 而不是一个对象。 In MY_APP, this refers to the global object. 在MY_APP中, this指的是全局对象。
Meaning that calling the function MY_APP(7) will assign v globally to the value of 7. (and in your case the function firstMethod would be declared globally). 这意味着调用函数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

To use MY_APP as an object, it needs to be instantiated, for instance 例如,要将MY_APP用作对象,需要对其进行实例化

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

will have obj1.v to be 3, and obj2.v to be 4. obj1.v为3, obj2.v为4。

Note you can also add methods using the prototype keyword (instead of this.firstMethod...) 请注意,您还可以使用prototype关键字(而不是this.firstMethod ...)添加方法

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

In the second case 在第二种情况下

  var MY_APP = { ... };

an object, one object, is created and its name is MY_APP. 创建一个对象, 一个对象,其名称为MY_APP。 The this keywords refers to that object, MY_APP. this关键字引用该对象MY_APP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Object构造函数和Global Object之间有什么区别 - What is the difference between Object constructor and Global Object JS:Object和Object.constructor之间的区别 - JS : Difference between Object and Object.constructor Number作为对象与Number作为构造函数的区别 - The difference between Number as an object and Number as a constructor 函数构造函数对象与对象内部对象之间的javascript区别 - javascript difference between function constructor object and an object inside object 原型对象和构造函数上的成员有什么区别? - What is the difference between members on prototype object and on constructor function? prototype.constructor和内置Object()有什么区别 - What is the difference between prototype.constructor and built-in Object() 使用继承时,构造函数和原型对象之间有什么区别吗? - Is there any difference between constructor function and prototype object when using inheritance? 原型:使用构造函数和对象本身之间的区别 - Prototype : difference between using constructor and just object itself Object.getPrototypeOf(x)和x.constructor.prototype之间的区别? - Difference between Object.getPrototypeOf(x) and x.constructor.prototype? 构造函数 function 和 function 返回 object 之间有什么区别? - What is the difference between a constructor function and function returning an object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM