我应该使用对象文字或构造函数吗?

cho*_*obo 92 javascript

我对在javascript中创建对象的方式感到困惑.似乎至少有两种方式.一种是使用对象文字符号,而另一种是使用构造函数.一个优于另一个有优势吗?

Ate*_*ral 127

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

var data = {
    foo: 42,
    bar: 43
};
Run Code Online (Sandbox Code Playgroud)

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

如果要向对象添加行为,可以使用构造函数并在构造期间向对象添加方法,或者为类提供原型.

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;
};
Run Code Online (Sandbox Code Playgroud)

像这样的类也像数据对象的模式:现在你有一些契约(通过构造函数)对象初始化/包含什么属性.免费文字只是一个无定形的数据.

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

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

function verify(data) {
    return data.foo === data.bar;
}
Run Code Online (Sandbox Code Playgroud)

然而,这对于封装来说是不利的:理想情况下,与实体相关联的所有数据+行为应该共存.

  • 如果将函数定义作为对象文字的一部分包含在内,或者在构造函数中使用`this.fn = function ...`方法,则每个对象实例都将拥有自己的函数副本.使用原型方法,您只需将一次函数附加一次:它们将通过原型继承由实例继承. (23认同)
  • 我相信你错过了一件重要的事情.只有构造函数可以提供私有成员以及公共成员(封装).在对象文字中 - 它们都是公开的. (14认同)
  • 很好的解释,但是如何将函数放在对象文字中呢?我以前见过这个.实际上下面的帖子有一个例子. (12认同)

ron*_*bot 87

它基本上归结为你是否需要多个对象实例; 使用构造函数定义的对象允许您拥有该对象的多个实例.对象文字基本上是单体,其变量/方法都是公共的.

// 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
Run Code Online (Sandbox Code Playgroud)


Jus*_*ago 9

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

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!
Run Code Online (Sandbox Code Playgroud)

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

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


小智 7

下面的代码显示了创建对象的三种方法,Object Literal语法,Function Constructor和Object.create().对象文字语法只是简单地创建和对象,因此它__prototype__Object对象,它可以访问所有的属性和方法Object.严格地说,从设计模式的角度来看,应该使用一个简单的Object文字来存储单个数据实例.

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

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);
Run Code Online (Sandbox Code Playgroud)


Koo*_*Inc 6

这取决于你想做什么.如果要在对象中使用(半)私有变量或函数,则可以使用构造函数.如果对象只包含属性和方法,则对象文字很好.

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

var SomeLiteral = {
    multiply5: function(i){ return i*5; }
}
Run Code Online (Sandbox Code Playgroud)

现在,该方法multiply5myObjSomeLiteral做同样的事情.唯一的区别是myObj使用私有变量.后者在某些情况下可能是有用的.大多数情况下,Object文字就足够了,并且是一种创建JS对象的简洁方法.


Shi*_*ala 5

在此处输入图片说明

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

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

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

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

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