js继承
原型链继承-Prototype chain
Child.prototype = new Parent();
借助原型链实现继承, 引起引用类型的原型属性会被所有实例共享
function Parent2() {
	this.name = 'parent2';
}
Parent2.prototype.say = function() {
	alert(this.name);
}
function Child2() {
	this.type = 'child2';
}
Child2.prototype = new Parent2();  // 缺点是父类构造函数执行两次
console.log(new Child2().say())
借助构造函数继承-constructed function
借助构造函数实现继承,子类不能继承父类prototype上的方法
function Parent1() {
	this.name = 'parent1';
}
Parent1.prototype.say = function() {
	alert(this.name);
}
function Child1() {
	this.type = 'child1';
	Parent1.call(this);
}
console.log(new Child1());
组合继承-combination
function Parent3() {
	this.name = 'parent3';
	this.play = [1, 2, 3];
}
Parent3.prototype.say = function() {
	alert(this.name);
}
function Child3() {
	this.type = 'child3';
	Parent3.call(this);
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play) // [1, 2, 3, 4],  [1, 2, 3];
共享原型-Shared-prototype
组合继承优化-1
Child.prototype = Parent.prototype
// 组合继承,优化1
function Parent4() {
	this.name = 'parent4';
	this.play = [1, 2, 3];
}
Parent4.prototype.say = function() {
	alert(this.name);
}
function Child4() {
	this.type = 'child4';
	Parent4.call(this);
}
Child4.prototype = Parent4.prototype;  // 缺点是,子类指向的构造函数与父类是一个
// Child4.prototype.constructor = Parent4;  // 这样无法区分父类的原型对象了
var s5 = new Child4();
var s6 = new Child4();
console.log(s5, s6);
console.log(s5 instanceof Child4,s5 instanceof Parent4);  // true, true
console.log(s5.constructor)  // Parent4
Object.create
组合继承优化-2
Child.prototype = Object.create(Parent.prototype)
function Parent5() {
	this.name = 'parent5';
	this.play = [1, 2, 3];
}
function Child5() {
	this.type = 'child5';
	Parent5.call(this);
}
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
var s7 = new Child5();
console.log(s7 instanceof Child5, s7 instanceof Parent5); // true, true
console.log(s7.constructor);  // Child5
你不知道的javascript之Object.create 和new区别
使用 class 关键字
class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height * this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }
}
var square = new Square(2);
写一个贴近实际开发原型链继承的例子-demo
写一个封装DOM查询的例子
function Elem(id) {
	this.elem = document.getElementById(id);
}
Elem.prototype.html = function(val) {
  var elem = this.elem;
  if (val) {
  	elem.innerHTML = val;
  	console.log(this)
  	return this; // 链式操作
  } else {
  	return elem.innerHTML;
  }
}
Elem.prototype.on = function(type, fn) {
	var elem = this.elem;
	if(elem.addEventListener) {
		elem.addEventListener('type', fn, false);
	} else if(elem.attachEvent) {
		elem.attachEvent('on' + type, fn);
	} else {
		elem['on' + type] = fn;
	}
    return this;
}
var div1 = new Elem('div1');
div1.html('有');
div1.on('click', alert('click')).html('youyi');

