js 继承(一)之原型链、借用构造函数、组合继承

前言 …

Just we

原型链

基本思想利用原型让一个引用类型继承另一个引用类型的属性和方法

function Father() {
    this.last_name = '张'
}
Father.prototype.sayLast_Name = function () {
    console.log('我的姓:' + this.last_name)
}
function Son() {
    this.first_name = '三'
}
Son.prototype = new Father()
Son.prototype.sayFirst_Name = function () {
    console.log('我的名字:'+ this.first_name)
}
var son = new Son()
son.sayLast_Name()
son.sayFirst_Name()

以上代码定义了两个类型:Father 和 Son 。每个类型有一个属性和一个方法。Son 继承了 Father,该继承是通过创建 Father 实例,将该实例赋给 Son.prototype 实现。实现的本质是重写 Son 原型对象,代之以 Father 的实例

这个例子中的实例以及构造函数和原型之间的关系如下图

在这里插入图片描述

原型链的问题

function Father() {
    this.hobbies = ['吃饭', '睡觉', '打豆豆']
}

function Son() {
}

Son.prototype = new Father()
var son_1 = new Son()
son_1.hobbies.push('学习')
console.log(son_1.hobbies)	// ["吃饭", "睡觉", "打豆豆", "学习"]
var son_2 = new Son()
console.log(son_2.hobbies)	// ["吃饭", "睡觉", "打豆豆", "学习"]
  • 在原型对象上定义的属性,会被所有实例共享
  • 在创建子类型 Son 的实例时,不能向超类型 Father 的构造函数中传递参数

借用构造函数

借用子类型构造函数的内部调用超类型的构造函数

function Father(last_name) {
    this.last_name = last_name
    this.hobbies = ['吃饭', '睡觉', '打豆豆']
}

function Son(last_name, first_name) {
    Father.call(this, last_name)
    this.first_name = first_name
}

var son_1 = new Son('张', '三')
son_1.hobbies.push('学习')
console.log(son_1.hobbies)  // ["吃饭", "睡觉", "打豆豆", "学习"]
var son_2 = new Son('张', '五')
console.log(son_2.hobbies)  // ["吃饭", "睡觉", "打豆豆"]

通过调用 call 方法,在创建的 Son 的实例环境下调用了 Father 的构造函数,这样一来,我们在创建 Son 的实例对象就可以执行 Father 的定义的所有对象的初始化代码。Son 的每个实例对象就会拥有自己的 hobbies 属性,以上代码也可以看出创建子类型 Son 的实例时,可以向超类型 Father 的构造函数中传递参数。

借用构造函数问题

function Father() {
}

Father.prototype.sayHello = function () {
    console.log('Hello JavaScript')
}

function Son() {
    Father.call(this)
}
 
var son = new Son()
son.sayHello()  //error

方法和函数都在构造函数中定义,所用类型只能使用构造函数模式,没有函数复用

组合继承

组合继承结合上述原型链和借用构造函数的优点,避免他们的缺陷

直接上代码

function Father(last_name) {
    this.last_name = last_name
    this.hobbies = ['吃饭', '睡觉', '打豆豆']
}

Father.prototype.sayName = function () {
    console.log(this.last_name + this.first_name)
}

function Son(last_name, first_name) {
    Father.call(this, last_name)
    this.first_name = first_name
}

Son.prototype = new Father()
var son_1 = new Son('张', '三')
son_1.hobbies.push('学习')
console.log(son_1.hobbies)  // ["吃饭", "睡觉", "打豆豆", "学习"]
var son_2 = new Son('张', '五')
console.log(son_2.hobbies)  // ["吃饭", "睡觉", "打豆豆"]
son_1.sayName() // 张三
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值