Javascript 我应该使用对象文字还是构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4859800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:27:03  来源:igfitidea点击:

Should I be using object literals or constructor functions?

javascript

提问by chobo

I am getting confused over which way I should be creating an object in javascript. It seems there are at least two ways. One is to use object literal notation while the other uses construction functions. Is there an advantage of one over the other?

我对应该以哪种方式在 javascript 中创建对象感到困惑。似乎至少有两种方法。一种是使用对象字面量表示法,而另一种是使用构造函数。一个比另一个有优势吗?

回答by Ates Goral

If you don't have behaviour associated with an object (i.e. if the object is just a container for data/state), I would use an object literal.

如果您没有与对象关联的行为(即,如果对象只是数据/状态的容器),我将使用对象字面量。

var data = {
    foo: 42,
    bar: 43
};

Apply the KISS principle. If you don't need anything beyond a simple container of data, go with a simple literal.

应用KISS 原则。如果除了简单的数据容器之外不需要任何东西,请使用简单的文字。

If you want to add behaviour to your object, you can go with a constructor and add methods to the object during construction or give your class a prototype.

如果要向对象添加行为,可以使用构造函数并在构造过程中向对象添加方法或为类提供原型。

function MyData(foo, bar) {
    this.foo = foo;
    this.bar = bar;

    this.verify = function () {
        return this.foo === this.bar;
    };
}

// or:
MyData.prototype.verify = function () {
    return this.foo === this.bar;
};

A class like this also acts like a schema for your data object: You now have some sort of contract (through the constructor) what properties the object initializes/contains. A free literal is just an amorphous blob of data.

像这样的类也充当数据对象的模式:您现在拥有某种契约(通过构造函数)对象初始化/包含哪些属性。自由文字只是无定形的数据块。

You might as well have an external verifyfunction that acts on a plain old data object:

您也可以拥有一个verify作用于普通旧数据对象的外部函数:

var data = {
    foo: 42,
    bar: 43
};

function verify(data) {
    return data.foo === data.bar;
}

However, this is not favorable with regards to encapsulation: Ideally, all the data + behaviour associated with an entity should live together.

然而,这对封装不利:理想情况下,与实体关联的所有数据 + 行为应该一起存在。

回答by ronnbot

It essentially boils down to if you need multiple instances of your object or not; object defined with a constructor lets you have multiple instances of that object. Object literals are basically singletons with variables/methods that are all public.

它本质上归结为是否需要对象的多个实例;使用构造函数定义的对象允许您拥有该对象的多个实例。对象字面量基本上是具有所有公共变量/方法的单例。

// define the objects:
var objLit = {
  x: 0,
  y: 0,
  z: 0,
  add: function () {
    return this.x + this.y + this.z;
  }
};

var ObjCon = function(_x, _y, _z) {
  var x = _x; // private
  var y = _y; // private
  this.z = _z; // public
  this.add = function () {
    return x + y + this.z; // note x, y doesn't need this.
  };
};

// use the objects:
objLit.x = 3; 
objLit.y = 2; 
objLit.z = 1; 
console.log(objLit.add());    

var objConIntance = new ObjCon(5,4,3); // instantiate an objCon
console.log(objConIntance.add());
console.log((new ObjCon(7,8,9)).add()); // another instance of objCon
console.log(objConIntance.add()); // same result, not affected by previous line

回答by JustcallmeDrago

Another way to create objects in a uniform way is to use a function that returns an object:

以统一方式创建对象的另一种方法是使用返回对象的函数:

function makeObject() {
    var that = {
        thisIsPublic: "a public variable"
        thisIsAlsoPublic: function () {
            alert(that.thisIsPublic);
        }
    };

    var secret = "this is a private variable"

    function secretFunction() { // private method
        secret += "!"; // can manipulate private variables
        that.thisIsPublic = "foo";     
    }

    that.publicMethod = function () {
        secret += "?"; // this method can also mess with private variables
    }

    that.anotherPublicVariable = "baz";

    return that; // this is the object we've constructed
}

makeObject.static = "This can be used to add a static varaible/method";

var bar = makeObject();
bar.publicMethod(); // ok
alert(bar.thisIsPublic); // ok
bar.secretFunction(); // error!
bar.secret // error!

Since functions in JavaScript are closures we can use private variables and methods and avoid new.

由于 JavaScript 中的函数是闭包,我们可以使用私有变量和方法并避免new.

From http://javascript.crockford.com/private.htmlon private variables in JavaScript.

来自http://javascript.crockford.com/private.html关于 JavaScript 中的私有变量。

回答by JOP

The code below shows three methods of creating an object, Object Literal syntax, a Function Constructor and Object.create(). Object literal syntax simply creates and object on the fly and as such its __prototype__is the Objectobject and it will have access to all the properties and methods of Object. Strictly from a design pattern perspective a simple Object literal should be used to store a single instance of data.

下面的代码显示了创建对象的三种方法、对象字面量语法、函数构造函数和Object.create(). 对象字面量语法只是动态地创建和对象,因此它__prototype__Object对象,它将可以访问Object. 严格地从设计模式的角度来看,应该使用简单的对象字面量来存储数据的单个实例。

The function constructor has a special property named .prototype. This property will become the __prototype__of any objects created by the function constructor. All properties and methods added to the .prototypeproperty of a function constructor will be available to all objects it creates. A constructor should be used if you require multiple instances of the data or require behavior from your object. Note the function constructor is also best used when you want to simulate a private/public development pattern. Remember to put all shared methods on the .prototypeso they wont be created in each object instance.

函数构造函数有一个名为 的特殊属性.prototype。此属性将成为__prototype__由函数构造函数创建的任何对象的 。添加到.prototype函数构造函数的属性的所有属性和方法将可用于它创建的所有对象。如果您需要数据的多个实例或需要对象的行为,则应使用构造函数。请注意,当您想要模拟私有/公共开发模式时,也最好使用函数构造函数。请记住将所有共享方法放在 上,.prototype这样它们就不会在每个对象实例中创建。

Creating objects with Object.create()utilizes an object literal as a __prototype__for the objects created by this method. All properties and methods added to the object literal will be available to all objects created from it through true prototypal inheritance. This is my preferred method.

创建对象Object.create()使用对象文字作为__prototype__此方法创建的对象。添加到对象字面量的所有属性和方法将可用于通过真正的原型继承从它创建的所有对象。这是我首选的方法。

//Object Example

//Simple Object Literal
var mySimpleObj = {
    prop1 : "value",
    prop2 : "value"
}

// Function Constructor
function PersonObjConstr()  {
    var privateProp = "this is private";
    this.firstname = "John";
    this.lastname = "Doe";
}
PersonObjConstr.prototype.greetFullName = function()    {
    return "PersonObjConstr says: Hello " + this.firstname + 
    " " + this.lastname;
};

// Object Literal
var personObjLit = {
    firstname : "John",
    lastname: "Doe",
    greetFullName : function() {
        return "personObjLit says: Hello " + this.firstname +
        ", " + this.lastname;
    }
} 

var newVar = mySimpleObj.prop1;
var newName = new PersonObjConstr();
var newName2 = Object.create(personObjLit);

回答by KooiInc

It depends on what you want to do. If you want to use (semi-)private variables or functions in you object, a constructor function is the way to do it. If your object only contains properties and methods, an object literal is fine.

这取决于你想做什么。如果你想在你的对象中使用(半)私有变量或函数,构造函数就是这样做的方法。如果你的对象只包含属性和方法,对象字面量就可以了。

function SomeConstructor(){
    var x = 5;
    this.multiply5 = function(i){
        return x*i;
    }
}
var myObj = new SomeConstructor;

var SomeLiteral = {
    multiply5: function(i){ return i*5; }
}

Now the method multiply5in myObjand SomeLiteraldo exactly the same thing. The only difference is that myObj uses a private variable. The latter may be usefull in some cases. Most of the times an Object literal is sufficient and a nice and clean way to create a JS-object.

现在,该方法multiply5myObjSomeLiteral做同样的事情。唯一的区别是 myObj 使用私有变量。后者在某些情况下可能有用。大多数情况下,对象字面量就足够了,并且是创建 JS 对象的一种漂亮而干净的方式。

回答by Shivprasad Ktheitroadala

enter image description here

在此处输入图片说明

Do you want single instance of the object for the page -- Literal.

您想要页面对象的单个实例 - 文字。

Do you want to just transfer data like DTO objects simple GET SET :- Literal

您是否只想传输数据,例如 DTO 对象简单的 GET SET :- 文字

Do you want to create real objects with method behaviors , multiple instances - Constructor function , Follow OOP principles , inheritance :- Constructor functions.

您想创建具有方法行为的真实对象,多个实例 - 构造函数,遵循 OOP 原则,继承:-构造函数。

Below is the youtube video which explains in detail what is literal , what are constructor functions and how they differ from each other.

下面是 youtube 视频,它详细解释了什么是字面量,什么是构造函数以及它们之间的区别。

https://www.youtube.com/watch?v=dVoAq2D3n44

https://www.youtube.com/watch?v=dVoAq2D3n44

回答by Alireza Fattahi

As mentioned in https://www.w3schools.com/js/js_object_definition.asp

https://www.w3schools.com/js/js_object_definition.asp 中所述

Using an object literal, you both defineand create, oneobject in onestatement.

使用对象文本,你俩定义创建一个在对象一个声明。

Also

Object literal only create a single object. Sometimes we like to have an object typethat can be used to create manyobjects of one type.

对象字面量只创建一个对象。有时我们喜欢有一个对象类型可以用来创建一个类型的多个对象。

回答by Tom

Go with object literal, it's more consise and expands better with the introduction of initial values.

使用对象字面量,随着初始值的引入,它更简洁,扩展性更好。

回答by techkuz

The Object() constructor function is a bit slower and more verbose. As such, the recommended way to create new objects in JavaScript is to use literal notation

Object() 构造函数有点慢而且更冗长。因此,在 JavaScript 中创建新对象的推荐方法是使用文字表示法

Udacity Object-Oriented JavaScript

Udacity 面向对象的 JavaScript

回答by yurin

Actually, methinks, we can have private methods in object literals. Consider code below:

实际上,我认为,我们可以在对象字面量中使用私有方法。考虑下面的代码:

var myObject = {

   publicMethod: function () {
      privateMethod1();
      privateMethod2(); 
      function privateMethod1(){
          console.log('i am privateMethod1');
      } 
      function privateMethod2(){
          console.log('i am privateMethod2');
      } 
   }

}

Matter of taste, but I prefer to use object literals where it is possible.

品味问题,但我更喜欢在可能的情况下使用对象文字。