我正在尝试理解javascript对象,但我在使用不同类型的声明时遇到了困难。
作为I read,有两种主要方式来定义对象
方法1:
var student1 = {
name: "Peter Foti",
course: 'JavaScript',
grade: 'A',
dispInfo: function(){
return this.name + ' has an ' + this.grade;
}
};
方法2:
function student (a, b, c) {
this.name = a;
this.course= b;
this.grade = c;
this.dispInfo = function(){
return this.name + ' has an ' + this.grade;
}
}
对于方法2,我理解这个概念,如果我想创建一个类型为student的变量,我只需要调用:
student1 = new student("Jean Dupont", "wine tasting", "A");
console.log(student1.dispInfo);
但是,使用方法1,如何在不重写所有内部函数(如dispInfo?)的情况下创建student2?
我想做点什么
var student2 = {
name: "Olivier Perraut",
course: 'Pétanque',
grade: 'F'
};
console.log(student2.getInfo);
答案 0 :(得分:2)
第一种方法是创建一个你只想打算一个的对象。这是单身人士。它直接创建student1
对象。
第二种方法是构造函数。可以反复使用构造函数来根据需要创建这些对象。
按照惯例,构造函数应该是最初的上限(例如,Student
而不是student
),就像JavaScript自己的对象(Date
,RegExp
,... )。
您可以使用JavaScript原型链,以便所有Student
个对象使用相同的dispInfo
函数(具有不同的this
值),而不是为dispInfo
创建function Student (a, b, c) {
this.name = a;
this.course = b;
this.grade = c;
}
Student.prototype.dispInfo = function(){
return this.name + ' has an ' + this.grade;
};
var s1 = new Student("Mary", "Algebra", "A");
var s2 = new Student("Joe", "Classical Sculpture", "B+");
每个对象:
var StudentPrototype = {
dispInfo: function(){
return this.name + ' has an ' + this.grade;
}
};
function BuildStudent(a, b, c) {
var student = Object.create(StudentPrototype);
student.name = a;
student.course = b;
student.grade = c;
return student;
}
var s1 = BuildStudent("Mary", "Algebra", "A");
var s2 = BuildStudent("Joe", "Classical Sculpture", "B+");
从ES5开始(对于旧浏览器也可以使用“垫片”),您不必使用构造函数来拥有共享原型的对象,您可以使用Object.create
来去做。我更喜欢构造函数,但您也可以使用 builder 函数:
new
请注意,我们不将Object.create
与构建函数一起使用,只需使用构造函数。 (如果你这样做通常是无害的,但对于阅读代码的人来说,这是不必要的和误导性的,所以你不想这样做。)
或者你甚至不需要在这个简单的情况下使用构建器函数,你可以直接使用{value: "the value"}
,但它有点麻烦,因为如果你传入属性描述符(第二个参数),每个< em> has 是一个描述属性的对象,而不仅仅是它的一个值(这是一个很好的理由),所以你必须做enumerable
(当然,你可能想要指定有关该属性的其他内容,例如是否为var StudentPrototype = {
dispInfo: function(){
return this.name + ' has an ' + this.grade;
}
};
var s1 = Object.create(StudentPrototype, {
name: {value: "Mary"},
course: {value: "Algebra"},
grade: {value: "A"}
});
var s2 = Object.create(StudentPrototype, {
name: {value: "Joe"},
course: {value: "Classical Sculpture"},
grade: {value: "B+"}
});
等):
Object.create
就个人而言,我更喜欢构造函数,但JavaScript的优点在于它支持多种编程风格,包括构建器或直接使用{{1}}等更合适的编程风格。
答案 1 :(得分:2)
JavaScript是一种所谓的基于原型的面向对象语言。这意味着对象不会通过类,特征,混合等来定义它们的行为,而是直接从其他对象继承它。
因此,如果您希望student2
的行为类似于student1
而只有一些细微差别,那么您只需继承student1
并覆盖那些不同的属性。在JavaScript中,使用Object.create
函数设置原型继承,该函数接受要继承的对象,并使用重写的属性设置可选的属性描述符映射。
var student1 = {
name: "Peter Foti",
course: 'JavaScript',
grade: 'A',
dispInfo: function() { return this.name + ' has an ' + this.grade; }
},
student2 = Object.create(student1, {
name: { value: 'Olivier Perraut' },
course: { value: 'Pétanque' },
grade: { value: 'F' }
});
console.log(student2.dispInfo());
// Olivier Perraut has an F
通常情况下,您会看到一种模式正在出现,而不是让“业务”对象直接相互继承,您将设置一个原始的“模板”对象并让所有业务对象继承自该模式,有点像这样:
var studentTemplate = {
dispInfo: function() { return this.name + ' has an ' + this.grade; }
},
student1 = Object.create(studentTemplate, {
name: { value: 'Peter Foti' },
course: { value: 'JavaScript' },
grade: { value: 'A' }
}),
student2 = Object.create(studentTemplate, {
name: { value: 'Olivier Perraut' },
course: { value: 'Pétanque' },
grade: { value: 'F' }
});
console.log(student1.dispInfo());
// PeterFoti has an A
console.log(student2.dispInfo());
// Olivier Perraut has an F
顺便说一下,我认为让dispInfo
成为getter属性而不是方法是个好主意:
var studentTemplate = {};
Object.defineProperty(studentTemplate, 'info', {
get: function() { return this.name + ' has an ' + this.grade; }
});
var student1 = Object.create(studentTemplate, {
name: { value: 'Peter Foti' },
course: { value: 'JavaScript' },
grade: { value: 'A' }
});
console.log(student1.info);
// PeterFoti has an A
答案 2 :(得分:0)
试试这个。虽然我更愿意采用方法2来实现这一点。
var student1 = {
name: "Peter Foti",
course: 'JavaScript',
grade: 'A',
dispInfo: function(){
return this.name + ' has an ' + this.grade;
}
};
function GenerateObject (objValues)
{
var object = Object.create(student1);
for(var i in objValues)
{
object[i] = objValues[i]
}
return object;
}
var student2 = GenerateObject({
name: "Olivier Perraut",
course: 'Pétanque',
grade: 'F'
});