1.原型继承
// 第一:原型继承 // 方法:让父类中的属性和方法在子类实例的原型链上 // 1. child.prototype = new father(200) // 2. child.prototype.constructor = child // 特点: // 1. 把父类的原型放到子类的实例的原型链上,实例调用这些方法,基于__proto__ 原型链查找机制完成的 // 2. 子类可以重写父类上的方法(会导致父类的其它实例有影响) // 3. 父类的私有或公有的属性方法,都会变成子类中公有的属性和方法 function A(x) { this.x = x } A.prototype.getX = function () { console.log(this.x) } function B(y) { this.y = y } B.prototype = new A(200) B.prototype.constructor = B B.prototype.getY = function () { console.log(this.y) } let b1 = new B(100); console.log(b1.y) // 100 b1.getY() // 100 b1.getX() //200
2.call继承
// 第二:call继承 // 方法:子类方法中把父类当作普通函数执行,让父类的this指向子类的实例,相当于给子类的实例设置了很多私有的属性和方法 // 1. 只能继承父类私有的属性或方法(因为是把父类当作普通函数执行的,和其原型上的属性方法没关系) // 特点: // 1. 父类私有的变子类私有的 function A(x) { this.x = x } A.prototype.getX = function () { console.log(this.x) } function B(y) { // this.B的实例b1 A.call(this,200) // b1.x = x this.y = y } B.prototype.getY = function () { console.log(this.y) } let b1 = new B(100); console.log(b1.x) // 200 console.log(b1.y) // 100 b1.getY() // 100 b1.getX() //200
3.寄生组合继承(call+原型creat)
// 第三:寄生组合继承(call+原型creat) // 方法:子类方法中把父类当作普通函数执行,让父类的this指向子类的实例,相当于给子类的实例设置了很多私有的属性和方法 // 1. 使用call继承父类私有的属性或方法(因为是把父类当作普通函数执行的,和其原型上的属性方法没关系) // 2. 使用Object.create(OBJ) // 特点: // 1. 父类私有和公有分别是子类私有和公有 function A(x) { this.x = x } A.prototype.getX = function () { console.log(this.x) } function B(y) { // this.B的实例b1 A.call(this,200) // b1.x = x this.y = y } // Object.create(OBJ):创建一个空对象,让空对象__proto__指向OBJ(或者说把OBJ作为新创建对象的原型) // Object.create(OBJ) 方法IE不兼容,所以自己写一个 B.prototype = Object.create(A.prototype) B.prototype.constructor = B B.prototype.getY = function () { console.log(this.y) } let b1 = new B(100); console.log(b1.x) // 200 console.log(b1.y) // 100 b1.getY() // 100 b1.getX() //200
4.重写Object.create(OBJ)方法
<script> // 重写Object.create(OBJ)方法 // 方法一:重写Object.create(OBJ)方法 // 原理:创建一个对象,让对象的原型链指向某一个东西 Object.create = function (obj) { let o = {}; o.__proto__ = obj; return o; // 意思对,但__proto__在IE不让用 } // 方法二: // 只要能创造某一个类的实例,那么这个实例原型链就指向当前类的原型,那么首先得有一个类,这个类的原型就是参数obj Object.create = function (obj) { function Fn() { }; // 创造一个类 Fn.prototype = obj; // 让这个类的原型指向obj return new Fn() // new Fn(),创造Fn类的实例,则这个实例原型链指向当前类Fn的原型obj } </script>
5.es6 继承
// 语法要求,基于class创造出的类不能当普通函数执行,如A(),所以call也无法使用, class A{ constructor(x){ this.x = x } getX(){ console.log(this.x) } } // 语法写法 // 原型上加方法如上getX // 原型上加属性如下 // A.prototype.shuxing = 'shuxingzhi' // class B{ // constructor(y){ // this.y = y // } // getY(){ // console.log(this.y) // } // } // =>ES6的继承 // class 子类 extends 父类 {} // =>B.prototype.__proto__ = A.prototype class B extends A{ constructor(y){ // 子类继承父类可以不写constructor,但写了constructor就必须写super(200); super相当于cal继承 super(200); // A.call(this,200) 把父类当作普通方法执行,给方法传递参数,让方法中的this是子类的实例 this.y = y } getY(){ console.log(this.y) } } // B.prototype = Object.create(A.prototype) //es6不允许重定向原型的指向 let b1 = new B(100) console.log(b1)
诗和远方success