JavaScript继承

JavaScript继承(摘抄自《JavaScript高级程序设计》)

  1. 原型链继承
    原理:利用原型对象和原型链链来实现属性和方法的访问

    	function Product(name) {
    		this.name = name
    	}
    	Product.prototype.getName = function() {
    		return this.name;
    	}
    	function Book(price) {
    		this.price = price;
    	}
    	Book.prototype = new Product();
    	var b1 = new Book('21);
    	b1.name = 'book';
    	console.log(b1.getName())	// book
    	console.log(b1.price)	// 21
    

    缺点:
    1.当存在引用类型的属性时,修改属性会影响到其它实例;
    2.在实例化子类时,无法给父类传参

  2. 借用构造函数(经典继承)
    原理:通过apply、call等调用父类的构造函数,来实现属性的继承

    	function Product(name) {
    		this.name = name
    	}
    	Product.prototype.getName = function() {
    		return this.name;
    	}
    	function Book(name, price) {
    		Product.call(this,name);
    		this.price = price;
    	}
    	Book.prototype.getPrice = function() {
    		return this.price;
    	}
    	var b1 = new Book('a book', 21);
    	console.log(b1.getPrice())	// 21
    	console.log(b1.getName())	// TypeError: b1.getName is not a function
    

    缺点:
    1.如果需要继承方法,就必须写在父类的构造函数中,每次创建新的实例时,都会创建一遍方法,浪费资源和性能

  3. 组合继承(伪经典继承)

    	function Product(name) {
    		this.name = name
    	}
    	Product.prototype.getName = function() {
    		return this.name;
    	}
    	function Book(name, price) {
    		Product.call(this,name);
    		this.price = price;
    	}
    	Book.prototype = new Product();
    	Book.prototype.getPrice = function() {
    		return this.price;
    	}
    	var b1 = new Book('a book', 21);
    	console.log(b1.getPrice())	// 21
    	console.log(b1.getName())	// "a book"
    

    优点:融合原型链继承和借用构造函数继承的优点,同时又都避免了双方的缺陷,是最常用的继承方式
    缺点:会调用两次父类构造函数

  4. 原型式继承
    原理:借助原型,并基于已有的对象,创建一个新的对象

    	function createObj(obj) {
    		function F() {};
    		F.prototype = obj;
    		return new F();
    	}
    

    缺点:实例会共享参数,同样无法避免引用类型值的问题的出现(ES5中的Object.create的模拟实现)

  5. 寄生式继承
    原理:与原型式继承类似,创建一个仅用于封装继承的函数,同时在函数内容增强对象。

    	function createAnther(obj) {
    		var clone = createObj(obj);
    		clone.sayHi = function() { console.log('hi') }
    		return clone;
    	}
    

    缺点:每次新建实例,都会创建一遍方法

  6. 寄生组合式继承

    	function inheritPrototype(sub, sup) {
    		var prototype = createObj(sup.prototype);
    		prototype.constructor = sub;	//	修改constructor指向
    		sub.prototype = prototype;	// 修正原型链
    	}
    	function Product(name) {
    		this.name = name
    	}
    	Product.prototype.getName = function() {
    		return this.name;
    	}
    	function Book(name, price) {
    		Product.call(this,name);
    		this.price = price;
    	}
    	inheritPrototype(Book, Product)
    	Book.prototype.getPrice = function() {
    		return this.price;
    	}
    	var b1 = new Book('a book', 21);
    

    优点:只调用了一次父类的构造函数,且原型链保持不变

你可能感兴趣的:(JS,JavaScript,继承)