/*** 借助構造函數實現繼承*/function Parent1(){this.name = "parent1";}Parent1.prototype.say = function(){};function Child1(){//將父構造函數的this指向子構造函數的實例上Parent1.call(this);//applythis.type = "child1";}console.log(new Child1);/*** 借助原型鏈實現繼承*/function Parent2(){this.name = 'parent2';this.play = [1,2,3];}function Child2(){this.type = 'child2';}Child2.prototype = new Parent2();console.log(new Child2);var s1 = new Child2();var s2 = new Child2();console.log(s1.play,s2.play);s1.play.push(4);/*** 組合方式* 缺點民:實例化兩次父類*/function Parent3(){this.name = "parent3";this.play = [1,2,3];}function Child3(){Parent3.call(this);this.type = 'child3';}Child3.prototype = new Parent3();var s3 = new Child3();var s4 = new Child3();s3.play.push(4);console.log(s3.play, s4.play);/*** 組合繼承的優化1*/function Parent4(){this.name = "parent4";this.play = [1,2,3];}function Child4(){Parent4.call(this);this.type = 'child4';}Child4.prototype = Parent4.prototype;var s5 = new Child4();var s6 = new Child4();console.log(s5, s6);console.log(s5 instanceof Child4,s5 instanceof Parent4);//構造函數是一個,無法判斷實例是父類創建還是子類創建 console.log(s5.constructor);/*** 組合繼承優化2*/function Parent5(){this.name = "parent5";this.play = [1,2,3];}function Child5(){Parent5.call(this);this.type = 'child5';}//創建中間對象Child5.prototype = Object.create(Parent5.prototype);Child5.prototype.constructor = Child5;var s7 = new Child5();console.log(s7 instanceof Child5, s7 instanceof Parent5);console.log(s7.constructor);
//模擬new func就是一個構造函數var new2 = function(func){//第一步,創建一個空對象,空對象關聯構造函數的原型對象var o = Object.create(func.prototype);//第二步,執行構造函數,k表示返回結果var k = func.call(o);//第三步,判斷構造函數的動行結果是不是對象類型if(typeof k === 'object'){return k;}else{return o;}}