理解javascript对象(不同类型的声明)

时间:2013-04-27 09:14:59

标签: javascript class object initialization

我正在尝试理解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);

3 个答案:

答案 0 :(得分:2)

第一种方法是创建一个你只想打算一个的对象。这是单身人士。它直接创建student1对象。

第二种方法是构造函数。可以反复使用构造函数来根据需要创建这些对象。

按照惯例,构造函数应该是最初的上限(例如,Student而不是student),就像JavaScript自己的对象(DateRegExp,... )。

您可以使用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'
    });