小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
JavaScript 继承 的学习
继承的几种方式
三种继承方式:
- 原型链、
- 对象冒充、
- 组合继承(原型链 + 对象冒充)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>三种继承: 原型链、对象冒充、组合继承(原型链+对象冒充)</title>
</head>
</html>
一、原型链继承:
// 存在的问题: //1: 当原型中存在引用类型时,存在数据修改时的问题 //2: 子类类型的对象无法给父类传参数
function Test(age) {
this.family = ['兄弟', '姊妹']
this.age = age
}
function Util() {}
Util.prototype = new Test(21)
var u1 = new Util()
u1.family.push('姐姐')
alert(u1.family) //["兄弟","姊妹","姐姐"]
var u2 = new Util()
alert(u2.family) //["兄弟","姊妹","姐姐"] 继承的是原型上的family是修改过的
二: 对象冒充继承(借用构造函数)
function Test(age) {
this.family = ['兄弟', '姊妹']
this.age = age
}
function Util(age) {
Test.call(this, age) //this指的是调用的对象即Util对象 call借用Test中的两个属性
}
var u = new Util(21)
alert(u.family) //\兄弟,姊妹
alert(u.age) //21
u.family.push('姐姐')
var uu = new Util(211)
alert(uu.family) //兄弟,姊妹 不会受到影响
三: 组合继承 (原型链+对象冒充)
function Test(age){
this.family = "兄弟,姊妹;
this.age = age;
}
Test.prototype.fun = function(){
return this.age + this.family;
}
function Util(age){
Test.call(this,age); //对象冒充
}
Util.prototype = new Test(); //原型链的方式
var u = new Util(26);
alert(u.age);
alert(u.family);
alert(u.fun());
四: 原型式继承: 相当于原型链的另一种写法(问题还是存在的)
function getObj(o) {
//返回原型是o的一个对象
function F() {}
F.prototype = o
return new F()
}
//原型对象
//使用字面量方式 定义
var person = {
name: 'Tom',
family: ['巴巴', '麻麻'],
}
var obj1 = getObj(person)
alert(obj1.name) // Tom
alert(obj1.family) // 巴巴,麻麻
obj1.family.push('大大')
var obj2 = getObj(person)
alert(obj2.family) //原型式继承存在引用类型共享的问题
五: 寄生式继承(原型式+工厂模式): 封装创建对象的过程
function getObj(o) {
//返回原型是o的一个对象
function F() {}
F.prototype = o
return new F()
}
//寄生函数
function createObj(o) {
var obj = getObj(o)
return obj
}
//原型对象
var person = {
name: 'Tom',
family: ['巴巴', '麻麻'],
}
var a = createObj(person)
a.family.push('大叔')
var b = createObj(person)
alert(b.family) //巴巴,麻麻,大叔