js/javascript 继承方式主要有哪些?及其优缺点特点

大家先看看这之前这篇文章,牢记一些概念。
链接: 构造函数,原型,实例的关系,原型链是什么.

// 1.原型链继承
// 先看个小栗子
function F(){
}
let s = new F()
Object.prototype.x = 1
console.log(s.x) // 1  通过原型链获得的x值
s.x = 2 
console.log(s.x) // 2 自己的x值
/*
// 以上是原型搜索机制,当以读取模式访问一个实例属性时,
// 先再实例搜索这个属性,如果没有会继续搜索原型

// 通过原型链实现的继承的情况下,搜索过程就可以一直沿着原型链继续找,
// 直到末端Object(原型链末端)的默认原型
*/


function Father(){
	this.v = 1
	this.arr = [6,6,6]
}

Father.prototype.func1 = function(){
	console.log('father')
}

function Son(){
	this.v = 2
}

// 继承
Son.prototype = new Father()
// Son.prototype 是Father的实例,所以获得了father的所有属性

// 创建儿子实例
let obj = new Son()

obj.func1() // father
// 方法重写,本质上是一个在自己身上的方法,不是通过原型链使用的父方法
// 另外注意,重写要在继承之后,因为原型的指向会发生改变
Son.prototype.func1 = function(){
	console.log('Son')
}

obj.func1() //Son

let obj2 = new Son()
obj2.arr.push(9)
console.log(obj.arr) //[6, 6, 6, 9] 
console.log(obj2.arr) //[6, 6, 6, 9] 

/*
// 可以看出优点是可以简单实现继承
// 缺点是引用类型数据,会被不同实例影响
*/

在这里插入图片描述
可以先看看这篇文章再理解下面的内容
链接: js简单理解call(),apply(),bind()和this.

// 2.借用构造函数
function F(x){
	this.arr = [1,1,1]
	this.x = x
}

function S(){
	// 继承
	F.call(this,'b')
	this.age = 1
}

let z = new S()
console.log(z)	//[1, 1, 1]

let c = new S()
c.arr.push(2) 
console.log(c)	//[1, 1, 1, 2]
/*
	// new 的方式调用构造函数实际上会经历以下4个步骤
	// 1创建一个新对象
	// 2将构造函数的作用域给新对象(使用call或者apply,所以this就指向了这个新对象)
	// 3执行构造函数中的代码(为这个新对象添加属性)
	// 4返回这新对象 给接收的实例变量
	用变量z做例子
	// 首先创建了一个新对象 假设是o
	// 在o的环境中调用构造函数,所以构造函数里面的this都是指向的这个o对象
	// 然后把里面的属性都给这个o
	// 返回o的地址给变量z接收
*/


/*
 // 优点可以不影响其他原型的情况下传递参数给上级构造函数,
 // 并且解决了引用类型数据的问题
 // 缺点是方法如果都定义在构造函数中的话,函数也就无法复用了,
 // 指的是每次都会在实例上//挂载一个新的function; 
 // 理解成没有挂载在原型上的方法就行了
*/
// 3.组合继承 (经典继承)
function F(x){
	this.x = x
	this.arr = [1,1,1]
}
F.prototype.func = function(){
	console.log(this.x)
}
function S(x,y){
	// 继承属性
	F.call(this,x)
	this.y = y
}

// 继承方法
S.prototype = new F()
S.prototype.func1 = function(){
	console.log(this.y)
}

let o1 = new S('o1',11)
o1.arr.push(2)
console.log(o1.arr) //[1, 1, 1, 2]
o1.func() // o1
o1.func1() // 11

let o2 = new S('o2',22)
console.log(o2.arr) // [1,1,1]
o2.func() // o2
o2.func1() // 22
/*
// 没有明显的缺点,主要是在继承属性和方法时都调用了一次父类,即执行了两次父类方法。
// 是使用比较多的继承方式,
// 另外还有原型式继承,寄生式继承,寄生组合式继承,有余力的同学可以了解一下
// 优点是解决了上面两个的缺点
*/

js 继承方式扩展(原型式,寄生式)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值