JS中的prototype、原型和繼承(ES5&ES6)

文章僅供學習,若是有補充的後期會加上,不按期更新添加新的內容,謝謝你們的支持!javascript

js中的方法通常分爲三種:java

1.類方法bash

2.對象方法函數

3.原型方法學習

function People(name){
	  this.name=name;
	  //對象方法
	  this.Introduce=function(){
	    console.log("My name is "+this.name);
	  }
	}
	//類方法
	People.Run=function(){
	  console.log("I can run");
	}
	//原型方法
	People.prototype.IntroduceChinese=function(){
	  console.log("個人名字是"+this.name);
	}	 
	//測試
	var p1=new People("Windking");
	p1.Introduce();
	People.Run();
	p1.IntroduceChinese();	
複製代碼

obj1.func.call(obj)方法; 意思是將obj當作obj1,調用func方法 、、這邊的意思是  後者調用前者的方法!! prototypes是什麼含義?測試

javascript中的每一個對象都有一個prototype屬性,javascript中對象的prototype屬性的解釋是:返回對象類型原型的引用。ui

function baseClass()
{
  this.showMsg = function()
  {
     alert("baseClass::showMsg");   
  }
}

function extendClass()
{
}

extendClass.prototype = new baseClass();
var instance = new extendClass();
instance.showMsg(); // 顯示baseClass::showMsg
複製代碼

咱們首先定義了baseClass類,而後咱們要定義extentClass,可是咱們打算以baseClass的一個實例爲原型,來克隆的extendClass也同時包含showMsg這個對象方法。extendClass.prototype = new baseClass()就能夠閱讀爲:extendClass是以baseClass的一個實例爲原型克隆建立的。那麼就會有一個問題,若是extendClass中自己包含有一個與baseClass的方法同名的方法會怎麼樣?this

function baseClass()
{
    this.showMsg = function()
    {
        alert("baseClass::showMsg");   
    }
}

function extendClass()
{
    this.showMsg =function ()
    {
        alert("extendClass::showMsg");
    }
}

extendClass.prototype = new baseClass();
var instance = new extendClass();

instance.showMsg();//顯示extendClass::showMsg
複製代碼

實驗證實:函數運行時會先去本體的函數中去找,若是找到則運行,找不到則去prototype中尋找函數。或者能夠理解爲prototype不會克隆同名函數。spa

那麼又會有一個新的問題:若是我想使用extendClass的一個實例instance調用baseClass的對象方法showMsg怎麼辦?答案是能夠使用call:prototype

extendClass.prototype = new baseClass();
var instance = new extendClass();

var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//顯示baseClass::showMsg

複製代碼

這裏的baseinstance.showMsg.call(instance);閱讀爲「將instance當作baseinstance來調用,調用它的對象方法showMsg」

好了,這裏可能有人會問,爲何不用baseClass.showMsg.call(instance);

這就是對象方法和類方法的區別,咱們想調用的是baseClass的對象方法

最後一段代碼更好的讓你們理解一下!!!

function baseClass(){
		this.name = "base";
		this.showMsg = function(){
		 console.log("baseClass::showMsg "+ this.name);   
		}
	}
	function extendClass(){
		this.name = "extend";
		this.showMsg = function(){
		 console.log("extendClass::showMsg "+this.name);   
		}
	}
	extendClass.prototype = new baseClass();
	var instance = new extendClass();
	instance.showMsg(); // 顯示extendClass::showMsg extend

	// 實驗證實:函數運行時會先去本體的函數中去找,若是找到則運行找不到則去prototype中尋找函數。或者能夠理解爲prototype不會克隆同名函數。

	var baseinstance = new baseClass();
	baseinstance.showMsg();   // 顯示baseClass::showMsg base
	baseinstance.showMsg.call(instance); // 顯示baseClass::showMsg extend
複製代碼

加一段代碼:

ES5的原型的繼承

function Super (name) {
    this.name = name;
    this.color = [1,2,3]; 
}

Super.prototype.SayName = function() {
    console.log(this.name);
}

function Sub (name, age) {
    Super.call(this, name);
    this.age = age;
}

Sub.prototype = Object.create(Super.prototype, {
    constructor: {
        value: Sub
    }
})

Sub.prototype.sayAge = function () {
    console.log(this.age);
}

let person1 =  new Sub('tom', 10);
person1.sayAge();
person1.SayName();
複製代碼

ES6:(Class extend)

class Super1 {
    constructor(name) {
        this.name = name;
    }
    SayName() {
        console.log( this.name);
    }
    static lagun() {
        console.log( this.hahatext);
    }
}

Super1.hahatext = 'liangying1';

class Sub1 extends Super1 {
    constructor(name, age) {
        super(Super1);
        this.age = age;
    }
    sayAge(){
        console.log(this.age);
    }
}

Sub1.hahatext = 'liangying2';
Super1.lagun();
Sub1.lagun();

console.log(Sub1.__proto__ === Super1);
console.log(Sub.prototype.__proto__ === Super.prototype );

console.log( 'server is wating' );
複製代碼
相關文章
相關標籤/搜索