1.什么是继承
使用继承的好处:代码复用,代码抽象
举个例子:classA,classB,classA中有一个方法,classB中也有一个方法,我们想使用classA,classB中的方法,如果不使用
继承,只能在classA中定义classB中的方法,或在classB中定义classA的方法,这样代码比较囊肿
继承可以解决,classA继承classB,classA就拥有了classB中的方法,方法直接copy给classA,这样就实现了继承
换句话:继承就是一种类与类之间的复制
在java中继承会用class关键字,但在es6以前并没class的概念,只有对象,es6引入了class关键字,但实际运用的还是原型链。
js继承就是对象拥有另一个对象的属性与方法,反观类,就是子类拥有父类的属性与方法,
由此我们联想到封闭一个函数实现简单的继承:
var obj = { name: "extend" };
var obj1 = { age: 20 }
function extend(original, target) {
for (var prop in original) {
if (original.hasOwnProperty(prop)) {
target[prop] = original[prop];
}
}
return target;
}
var newObj = extend(obj, obj1);
用es6中的方法Object.assign()也可以现实
但是这个会有一个缺陷,当父对象中的属性是一个引用类型时,在子对象中修改时,会造成父对象的引用类型改变
有人可能会想到深度克隆,但这样会循环引用
**利用原型链**
var obj = {};
当我们取obj.name时,先看自身的原型上是否有此属性,没有的话会从obj.__proto__开始向上寻找直到找到Object.prototype,
如果依然没有,返回undefined
在每一个函数的原型上都有一个"constructor"属性函数指向自已,
function func() { }
console.log(func.prototype);
// 我们就可以用这个特性实现继承
function Fn1() {
}
function Fn2() {
}
Fn1.prototype = Fn2;
Fn1.prototype.constructor = Fn1;
var fn = new Fn1();
还有一种方式:ES5提供 Object.create()方法更加方便,直接把传入的对象用做创建对象的原型(prototype)
var obj1 = {}
var obj = Object.create(obj1)
**另外在提下new:**
在java中new是实例化一个类,但在js中并不是,它只是改变函数调用方式
用new来调用函数有什么不同:
1.创建一个对象
2.将新函数的prototype绑定到调用函数的prototype
3.绑定this并调用
代码表示 :
function New(fn) {//参数为函数
var obj = {};
obj.__proto__ = fn.prototype;
fn.call(obj);
return obj;
}