1. 程式人生 > >自我學習之es6(6)

自我學習之es6(6)

es6的新特性裡增加了類和類的繼承,其實這個特性也是向後臺語言借鑑過來的,先來看下es5的時候如何構造一個物件

function Human(){
  this.eyes=2;
  this.hands=2;
}

Human.prototype.singing=function(){
	console.log('I can sing');
}

let a = new Human();
console.log(a);

a.singing();
如上,用es5的方法構造了一個叫Human的物件,在物件裡建立了2個屬性,並用prototype的方法掛載了一個方法,申明瞭一個a為Human物件的例項化,並用這個a呼叫singing這個方法

再來看,如何用es6來申明一個類:

class Human{
	constructor(){
		this.eyes=2;
		this.hands=2;
	}
}

let a = new Human();
console.log(a);

es6用class關鍵字來申明一個類,並用constructor來建立一個類的建構函式,初始化一個物件的屬性,其實es6只是用了一種更語義化、更規範的方式去申明一個類,但是其背後的原理還是基於es5的,如果要建立一個方法,也無需再掛載到原型上 直接在物件裡建立

class Human{
	constructor(){
		this.eyes=2;
		this.hands=2;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human();
console.log(a);

a.singing();
es6裡是如何繼承類的呢
class Human{
	constructor(){
		this.eyes=2;
		this.hands=2;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human();
console.log(a);

a.singing();

class NormalMan extends Human {

}

let b=new NormalMan();
console.log(b);

類可以繼承另外一個類,使用extends語法,可以繼承到另外一個類的所有屬性和方法,除此之外,它也可以改造繼承過來的屬性和方法或者建立新的屬性和方法

class Human{
	constructor(){
		this.eyes=2;
		this.hands=2;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human();
console.log(a);

a.singing();

class NormalMan extends Human {
  	constructor(){
  		super();
		this.eyes=100;
		this.hands=200;
		this.feet=2;
	}

	singing(){
		console.log('NormalMan can sing');
	}
	run(){
		console.log('NormalMan can run');
	}
}

let b=new NormalMan();
console.log(b);
b.singing();
b.run();
可以在constructor裡改造繼承過來的屬性,還可以新建自己的方法,super()呼叫了一下父類的建構函式,當繼承了另外一個類的時候就必須使用,如果不用就會報錯。

我們可以在父類的建構函式裡傳參,在呼叫的時候傳參

class Human{
	constructor(eyes=2,hands=2){
		this.eyes=eyes;
		this.hands=hands;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human(3,4);
console.log(a);

a.singing();

class NormalMan extends Human {
  	constructor(){
  		super();
		this.eyes=100;
		this.hands=200;
		this.feet=2;
	}

	singing(){
		console.log('NormalMan can sing');
	}
	run(){
		console.log('NormalMan can run');
	}
}

let b=new NormalMan();
console.log(b);
b.singing();
b.run();
super()裡呼叫的是父類的建構函式,所以super()裡也可以傳參
class Human{
	constructor(eyes=2,hands=2){
		this.eyes=eyes;
		this.hands=hands;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human(3,4);
console.log(a);

a.singing();

class NormalMan extends Human {
  	constructor(){
  		super(1000,2000);
		this.feet=2;

	}

	singing(){
		console.log('NormalMan can sing');
	}
	run(){
		console.log('NormalMan can run');
	}
}

let b=new NormalMan();
console.log(b);
b.singing();
b.run();

關於建構函式裡的this指向,我們可以在繼承的函式的建構函式裡面傳一個name的引數,並在建構函式裡新建一個name的屬性,在singing()的方法裡可以用模板字串${this.name}去拼接,最後在例項化的NormalMan()裡傳入Mike,最後打印出來NormalMan這個物件裡有name: "Mike"

如果用另外一個變數去接收b裡面singing的方法 ,再呼叫這個方法,這個時候就和執行一個普通函式一樣,這時再去列印this,this就為undefined

class Human{
	constructor(eyes=2,hands=2){
		this.eyes=eyes;
		this.hands=hands;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human(3,4);
console.log(a);

a.singing();

class NormalMan extends Human {
  	constructor(name='Flowke'){
  		super(1000,2000);
		this.feet=2;
        this.name=name;
	}

	singing(){
		console.log(this);
		/*console.log(`${this.name} can sing`);*/
	}
	run(){
		console.log('NormalMan can run');
	}
}

let b=new NormalMan('Mike');
console.log(b);
b.singing();
b.run();

let fnn=b.singing;
fnn();
那該怎麼去解決這個問題呢,如何讓這個this永遠指向new出來的這個例項?可以在constructor的建構函式裡寫上這句 this.singing=this.singing.bind(this);
class Human{
	constructor(eyes=2,hands=2){
		this.eyes=eyes;
		this.hands=hands;
	}

	singing(){
		console.log('I can sing');
	}
}

let a = new Human(3,4);
console.log(a);

a.singing();

class NormalMan extends Human {
  	constructor(name='Flowke'){
  		super(1000,2000);
		this.feet=2;
        this.name=name;
        this.singing=this.singing.bind(this);
	}

	singing(){
		/*console.log(this);*/
		console.log(`${this.name} can sing`);
	}
	run(){
		console.log('NormalMan can run');
	}
}

let b=new NormalMan('Mike');
console.log(b);
b.singing();
b.run();

let fnn=b.singing;
fnn();
this.singing=this.singing.bind(this);後面的this.singing就是指後面的singing()這個方法,後面綁定了this,那這個時候let fnn=b.singing,這裡的b.singing訪問的就是this.singing,而這裡this.singing已經綁定了this的指向,這個時候去執行fnn,而這個this就是指構造的時候類的例項,這個時候執行fnn,就會發現打印出來的是mike也就是b這個例項化物件