我对在javascript中创建对象的方式感到困惑。似乎至少有两种方式。一种是使用对象文字符号,而另一种是使用构造函数。一个人有优势吗?
答案 0 :(得分:125)
如果没有与对象关联的行为(即,如果对象只是数据/状态的容器),我会使用对象文字。
var data = {
foo: 42,
bar: 43
};
应用KISS principle。如果除了简单的数据容器之外不需要任何东西,请使用简单的文字。
如果要向对象添加行为,可以使用构造函数并在构造期间向对象添加方法,或者为类提供原型。
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;
};
这样的类也像数据对象的模式一样:现在你有一些契约(通过构造函数)对象初始化/包含什么属性。免费文字只是无数的数据。
您可能还有一个外部verify
函数,它可以作用于普通的旧数据对象:
var data = {
foo: 42,
bar: 43
};
function verify(data) {
return data.foo === data.bar;
}
然而,这对于封装来说是不利的:理想情况下,与实体相关的所有数据+行为都应该共存。
答案 1 :(得分: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
答案 2 :(得分: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!
由于JavaScript中的函数是闭包,我们可以使用私有变量和方法,并避免使用new
。
来自http://javascript.crockford.com/private.html的JavaScript中的私有变量。
答案 3 :(得分: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);
答案 4 :(得分: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; }
}
现在multiply5
和myObj
中的方法SomeLiteral
完全相同。唯一的区别是myObj使用私有变量。后者在某些情况下可能是有用的。大多数情况下,Object文字就足够了,并且是一种创建JS对象的简洁方法。
答案 5 :(得分:4)
你想要页面的对象的单个实例 - Literal。
您是否只想传输数据,如DTO对象简单GET SET: - Literal
您是否希望使用方法行为,多个实例创建真实对象 - 构造函数,遵循OOP原则,继承: - 构造函数。
下面是youtube视频,详细解释了什么是文字,什么是构造函数以及它们之间的区别。
答案 6 :(得分:1)
使用对象文字,通过引入初始值,它更简洁,扩展性更好。
答案 7 :(得分:1)
正如https://www.w3schools.com/js/js_object_definition.asp
中所述使用对象文字,您在一个中定义和创建,一个对象 言。
另外
对象文字只创建一个对象。有时我们喜欢 对象类型,可用于创建一种类型的多个对象。
答案 8 :(得分:0)
Object()构造函数稍微慢一些,也更冗长。如 这样,建议在JavaScript中创建新对象的方法是 使用文字符号
答案 9 :(得分:0)
实际上,方法上,我们可以在对象常量中使用私有方法。考虑下面的代码:
var myObject = {
publicMethod: function () {
privateMethod1();
privateMethod2();
function privateMethod1(){
console.log('i am privateMethod1');
}
function privateMethod2(){
console.log('i am privateMethod2');
}
}
}
有一些品味,但我更喜欢在可能的情况下使用对象文字。
答案 10 :(得分:0)
这是一个基准,显示了访问文字、构造函数和类上的属性的访问时间。这可能需要一段时间,但它显示了几乎所有访问属性的方法。对我来说,这个基准测试显示字面属性访问时间总体上比类和构造函数属性访问时间稍慢。性能最差的时间来自对象文字上的 getter 和 setter。与类和构造函数上的 getter 和 setter 不同,它们似乎比大多数其他访问时间更快。 基准:https://www.measurethat.net/Benchmarks/Show/12245/0/the-grand-dictionary-property-accessor-schema
答案 11 :(得分:-1)
// Object Literal和Object构造函数
function MyData(foo, bar) {
this.foo = foo;
this.bar = bar;
}
MyData.prototype.verify = function () {
return this.foo === this.bar;
};
//add property using prototype
var MD = new MyData;//true.
var MD = new MyData();//true.
MD.verify// return only the function structure.
MD.verify(); //return the verify value and in this case return true coz both value is null.
var MD1 = new MyData(1,2); // intialized the value at the starting.
MD1.verify// return only the function structure.
MD1.verify(); // return false coz both value are not same.
MD1.verify(3,3);// return false coz this will not check this value intialized at the top
MyData.prototype.verify = function (foo,bar) {
return this.foo === this.bar;
};
var MD1 = new MyData(1,2);
MD1.verify();
MD1.verify(3,3);// return false coz this keyword used with foo and bar that will check parent data