平时不怎么用的一些知识,过段时间就开始模糊不清了,这已经不知道是第几次再回头来看原型继承的方式了,索性重新整理一遍,方便下次回顾,若有不正确或需要补充的欢迎留言
在ES6之前,JS实现继承的方式不止一种,因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。
下面整理几种常见的继承方式:
对象冒充 - 使用最原始的方法
function Person(name) {
this.name = name;
this.sayName = function () {
console.log(this.name)
}
}
function Student(age) {
this.age = age;
this.sayAge = function () {
console.log(this.age)
}
}
因为构造函数也只是一个函数,所以可使 Person 构造函数成为 Student 的方法,然后调用它。Student 就会收到 Person 的构造函数中定义的属性和方法。
function Student(name,age) {
// 函数命名只是指向引用地址(指针)
this.newMethod = Person;
this.newMethod(name);
// 删除对 Person 的引用,后面就不能继续调用了
delete this.newMethod;
// 新的属性和方法必须在删除新方法后定义,否则可能发生覆盖
this.age = age;
this.sayAge = function () {
console.log(this.age)
}
}
新建实例测试上面的方式:
var per = new Person('小明')
var stu = nww Student('小红',13)
per.sayName() // 输出 小明
stu.sayName() // 输出 小红
stu.sayAge() // 输出 13
对象冒充 - 使用 call() 方法
使用 call() 方法和上面这种对象冒充方法很相似,还是使用上面的示例
function Person(name) {
this.name = name;
this.sayName = function () {
console.log(this.name)
}
}
// call() 第一个参数用作 this 的对象,其他参数都直接传递给函数自身
function Student(name) {
Person.call(this,name)
}
// 实例化
var stu = new Studeng('小明')
stu.sayName() // 输出 小明
console.log(stu.name) // 输出 小明
拷贝继承 - 使用 for in 遍历拷贝
使用for in遍历需要继承的对象,将属性和方法逐一拷贝实现继承,就上边的例子,通常,我们会把公共的方法放到原型上,如下:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
// 此时只将构造函数本身的属性继承了
function Student(name) {
Person.call(this,name)
}
// 使用for in遍历继承 Person 原型上的方法
for(var key in Person.prototype) {
Student.prototype[key] = Person.prototype[key]
}
// 此时实例化,严重结果
var stu = new Student('小明')
stu.syaName() // 输出 小明,说明继承了 Person 原型上的 sayName 方法
原型继承
原型对象 prototype 的任何属性和方法都被传递给那个类的所有实例。故可以利用这种功能实现继承机制
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log(this.name)
}
function Student(name) {
Person.call(this.name)
}
// 利用原型的特性实现继承
Student.prototype = new Person()
var stu = new Student('小明')
stu.sayName() // 输出 小明
还有其他方式,后面再补充吧