1. 混入式继承 -- extend 拷贝
2. 原型链继承 原型替换 constructor
3. 混入+原形链继承
4. 经典继承 :Object.create() 传入的作为新创建出来对象的原型。新创建的对象继承了传入的
5. 用call/apply 改变this让成为自己,继承别人的属性
1.混入继承:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 继承
// 面向对象三大特征:
// 1. 封装 render move
// 2. 继承:在js中,指的是对象与对象之间的关系。一个对象没有的成员,另外一个对象有,拿过来直接使用就实现了继承。
// 3. 多态
var dacongge = {
skill: "liaomei",
car: "法拉利",
moeny: 10000000,
house: "蒙古海景房",
}
var lianjie = {
son: "二狗子",
}
// lianjie ==> Object.prototype ==> null;
var xm = {
name: "小明"
}
// 第一种继承方式: 混入式继承: 拷贝一个对象的属性(成员)
// xm.skill = dacongge.skill;
// xm.car = dacongge.car;
// xm.moeny = dacongge.moeny;
// 上面的写法比较麻烦,直接遍历dacongge,给xm添加即可
/*for(var k in dacongge){
xm[k] = dacongge[k];
}
for(var k in lianjie){
xm[k] = lianjie[k];
}*/
Object.prototype.gender = "male";
// 把上面的代码直接封装作为xm的一个方法
// extend 拓展
xm.extend = function (obj) {
for(var k in obj){
// 把obj对象自身的成员添加给this即可
if(obj.hasOwnProperty(k)){
// k 是对象自己本身的
this[k] = obj[k];
}
}
}
xm.extend(dacongge);
xm.extend(lianjie);
console.log(xm);
</script>
</body>
</html>
2.原形链继承:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 原型链继承
function Person(){
}
// 原型对象
/*Person.prototype.color = "lime";
Person.prototype.sayHi = function () {
console.log("sayHi");
}
Person.prototype.render = function () {
console.log("render");
}
Person.prototype.move = function () {
console.log("move");
}*/
// ....
// 上面给原型添加的成员,实例对象p都可以访问到,但是写法麻烦 -- 优化
// 原型替换
// 造成一个问题: constructor 属性丢失
// 解决办法: 就是手动添加constructor 属性
/*Person.prototype = {
constructor: Person,
color : "lime",
sayHi : function () {
console.log("sayHi");
},
render : function () {
console.log("render");
},
move : function () {
console.log("move");
}
}*/
// 实例对象
var p = new Person();
// 实例对象可以直接访问原型对象上的所有成员 --- 原型链继承
// console.log(p.color);
// p.sayHi();
// p的原型链:
// 没有原型替换的原型链:
// p ==> Person.prototype(默认的原型对象{constructor: Person}) ==> Object.prototype ==> null
// 原型替换后的原型链:
// p ==> Person.prototype(新的对象) ==> Object.prototype ==> null
// constructor ==> Object
// 原型替换后,constructor 属性访问得到的结果是 Object,原因是因为 替换后的原型对象上没有constructor属性。
console.log(p.constructor); // Object
// 小结:
// 原型链继承:
// 写法有两种:
// 给原型对象添加属性
// 原型替换, 把一个新的对象赋值给原型对象
// 问题: constructor 属性丢失了
// 办法: 手动添加constructor属性
</script>
</body>
</html>
3.原型继承+混入继承:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 需求: 让Person所有的实例对象可以访问到lw dacongge的成员
function Person(){
}
// 混入 + 原型链继承
// 思路: 把lw dacongge的成员添加到Person的原型上,所有的实例对象都可以继承到原型上.
// 混入式继承
Person.prototype.extend = function (obj) {
for(var k in obj){
if(obj.hasOwnProperty(k)){
this[k] = obj[k];
}
}
}
var p = new Person();
var lw = {
skill: "FQ",
handsome: "very handsome",
healthy: "都说好"
}
var dacongge = {
money: 10000000,
house: "新疆海景房"
}
// 原型上就有了lw的成员
Person.prototype.extend(lw);
Person.prototype.extend(dacongge);
// console.log(Person.prototype);
// 原型链继承
console.log(p.handsome);
console.log(p.house);
</script>
</body>
</html>
4. 经典继承:
就是用一个方法创建了一个空对象(下图中的对象o),这个空对象把传入create()中的那个对象作为了自己的原型。那么就自然可以调用传入对象上的(“自己原型”)属性和方法(当成自己的了)
5.借用构造函数继承: