Javascript 面向对象编程(三)

170 阅读2分钟

理解什么是继承

方法和属性从一个类传递到另一个类的过程

为什么需要继承机制

  funtion Person(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }
  Person.prototype.sayHi = function() {
    return "Hi" + this.firstName + " " + this.lastName;
  }

  function Student(firstName, lastName){
    return Person.apply(this, arguments);
}

Student.prototype.sayHi = function(){
    return "Hi " + this.firstName + " " + this.lastName;
}

我们真的需要在学生身上重新定义sayHi吗?这似乎重复…… 那怎么办?

function Person(firstName, lastName){
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.sayHi = function(){
    return "Hi " + this.firstName + " " + this.lastName;
}

将一个对象的原型属性指定为另一个对象的原型属性!

function Student(firstName, lastName){
    return Person.apply(this, arguments);
}

Student.prototype = Person.prototype;

var s1 = new Student('李','哈')
s1.sayHi() // "Hi 李 哈"

有用:)!

继续看看 在Student prototype对象上添加一些别的

  Student.prototype.status = function(){
    return 'I am currently a student'
  }

让我们用Person创建一个对象

  var p1 = new Person('下','啦')
  p1.status() // 'I am currently a student'

哦哦……为什么Person原型有student原型的属性?学生继承的是人,而不是人。

问题

  • 我们不能将一个对象分配给另一个对象——它只会创建一个引用!
  • 如果我们改变Student.prototype,会影响Person.prototype
  • 我们仍然需要来自父类原型的所有方法和属性,但是我们想要两个完全独立的对象——而不是引用!

一个更好的选择Object.create

创建一个全新的函数并接受它的第一个参数,即新创建对象的原型对象。

function Student(firstName, lastName){
    return Person.apply(this, arguments);
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.status = function(){
    return "I am currently a student!"
}
var p1 = new Person('李', '哈');
p1.status; // undefined 

Student.prototype 不会影响 Person.prototype !

思考为什么不是new?

function Student(firstName, lastName){
    return Person.apply(this, arguments);
}

Student.prototype = new Person();
// 1. Person被执行了两次
// 2. 代码重复,增加了多余的不需要的属性在Student的原型对象上面

优化一下

function Student(firstName, lastName){
    return Person.apply(this, arguments);
}

Student.prototype.sayHi = function(){
    return "Hello " + this.firstName + " " + this.lastName;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor; // Person
Student.prototype.constructor = Student;

继承的两个要点

  • 将原型设置为使用另一个原型创建的对象
  • 重置构造函数属性

总结

  • 每次使用new关键字时,在创建的对象和构造函数的prototype属性之间建立一个链接——可以使用__proto__访问这个链接
  • prototype对象包含一个名为构造函数的属性,该属性指向构造函数
  • 为了共享由构造函数创建的对象的属性和方法,将它们放在原型中,因为它是最有效的。
  • 要将方法和属性从一个原型对象传递到另一个原型对象,我们可以使用继承,其中包括使用对象将prototype属性设置为新创建的对象。创建并重新设置构造函数属性