我对应该使用javascript创建对象的方式感到困惑。似乎至少有两种方法。一种是使用对象文字符号,而另一种是使用构造函数。有一个相对于另一个的优势吗?
我对应该使用javascript创建对象的方式感到困惑。似乎至少有两种方法。一种是使用对象文字符号,而另一种是使用构造函数。有一个相对于另一个的优势吗?
Answers:
如果您没有与对象关联的行为(即,如果该对象只是数据/状态的容器),则可以使用对象文字。
var data = {
foo: 42,
bar: 43
};
应用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;
};
这样的类也像数据对象的架构一样工作:您现在(通过构造函数)具有某种约定(通过构造函数),该对象初始化/包含哪些属性。一个自由的文字只是数据的一个无定形的斑点。
您也可能有一个verify作用于普通旧数据对象的外部函数:
var data = {
foo: 42,
bar: 43
};
function verify(data) {
return data.foo === data.bar;
}
但是,这在封装方面是不利的:理想情况下,与实体关联的所有数据和行为都应一起存在。
this.fn = function ...在构造函数中使用该方法,则每个对象实例将具有自己的函数副本。使用原型方法,您只需一次附加每个函数:实例将通过原型继承来继承它们。
本质上可以归结为是否需要对象的多个实例。使用构造函数定义的对象使您可以拥有该对象的多个实例。对象字面量基本上是具有所有公共变量/方法的单例。
// 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
以统一方式创建对象的另一种方法是使用返回对象的函数:
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中的私有变量。
下面的代码显示了三种创建对象的方法: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);
Object.create文字内部的函数创建对象时,每个实例将是唯一的?
这取决于您想做什么。如果要在对象中使用(半)私有变量或函数,则可以使用构造函数。如果您的对象仅包含属性和方法,则可以使用对象文字。
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对象的一种好方法。
您是否需要页面对象的单个实例-文字。
您是否只想像DTO对象那样传输数据,简单的GET SET:-文字
您是否要创建具有方法行为,多个实例的真实对象-构造函数,遵循OOP原则,继承:-构造函数。
以下是youtube视频,详细说明了什么是文字,什么是构造函数以及它们之间的区别。
与对象文字一起使用时,它更加简洁,并且通过引入初始值可以更好地扩展。
如https://www.w3schools.com/js/js_object_definition.asp中所述
使用对象文本,你俩定义和创建, 一个在对象一个 声明。
也
对象文字只能创建一个对象。有时我们喜欢拥有一个对象类型,该对象类型可用于创建一种类型的许多对象。
Object()构造函数比较慢一些,也很冗长。因此,建议在JavaScript中创建新对象的方法是使用文字符号
//对象文字和对象构造函数
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