Javascript对象练习


1.对象构造函数的创建及实例化

/* 创建对象的属性在构建造函数中声明 */
function Person(first, last, age, gender){
    this.name = {
        first:first,
        last:last
    }
    this.age = age;
    this.gender = gender;
}

/* 性能考量
如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。
例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用,方法都会被重新赋值一次(也就是说,为每一个对象的创建)。
参见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures */
/* 创建对象的方法在对象的原型对象(prototype属性)中添加 */
Person.prototype.greeting = function(){
    alert('Hello,I\'m ' + this.name.first + ' ' + this.name.last);
};

/* 实例化 */
/* 当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。 */
marry = new Person('Marry', 'Jane', '23', 'female');

/* 测试 */
marry.name.first;   // "Marry"
marry.greeting();   // [Hello,I'm Marry Jane]

一个类的基本属性应该在创建之前就想好,并且都应该放置在构造函数中。因为创建好的构造函数无法动态修改,如果要想给类A的构造函数添加新的属性,那还是创建一个类A的子类吧。

那么为什么类的方法要在类的原型对象中定义呢。

/* 在上述构造函数基础上,要如何才能获取对象的全名(fullname)呢? */
/* 一方面是上面所说的 性能考量 */
/* 另一方面,如果我希望每个Person类的实例都能获取全名的话,就要在prototype中添加咯,毕竟构造函数没法修改 */

/* 试想1.直接用fullname属性获取对象全名 */
Perosn.prototype.fullname = this.name.first + ' ' + this.name.last;     // 调用fullname属性时,this绑定在window,并不是目标对象。

/* 测试 */
marry.fullname; // "undefined undefined"

/* 试想2.使用方法获取对象全名 */
Person.prototype.fullname = function(){
    return this.name.first + ' ' + this.name.last;
};  // 很明显,试想2成功了,因为在函数中的this绑定在目标对象上

/* 测试 */
marry.fullname();   // "Marry Jane"

2.对象的继承

/* 原型链继承测试 */
marry.__proto__===Person.prototype;

/*  属性的继承 */
/* 这里使用了Function.call(),第一个参数指明了在你运行这个函数时想对“this”指定的值,也就是说,你可以重新指定你调用的函数里所有“this”指向的对象。其他的变量指明了所有目标函数运行时接受的参数。
再加之,new创建新对象时,将this绑定到新创建的对象。所以属性的继承到此结束*/
function Student(first, last, age, gender, grade, school){
    Person.call(this,first, last, age, gender);
    this.grade = grade;
    this.school = school;
}

/* 测试 */
tom.name;   // {first: "Tom", last: "Smith"}
tom.grade;  // 3
tom.greeting(); // Uncaught TypeError

/* 方法的继承 */
/* Javascript的继承是基于原型链的,方法和属性首先会在对象中搜索,如果没有搜索到则会到对象的原型对象的prototype中搜索,直到找到或者找不到而终止。
参见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
prototype 属性的值是一个对象,我们希望被原型链下游的对象继承的属性和方法,都被储存在其中。 */
/* 这里使用的Object.create()函数,以Person.prototype的为原型创建一个新的对象 */
Student.prototype = Object.create(Person.prototype);
/* 因为constructor属性指向对象的构造器函数,所以Person.prototype的constructor指向的是Person,这里应该修改成Student,以避免在以后的使用中发生错误。 */
Student.prototype.constructor = Student;

/* 原型链继承测试 */
tom.__proto__.__proto__ === Person.prototype;
tom.__proto__ === Student.prototype;

你可能感兴趣的:(Javascript对象练习)