摘要:聲明和定義聲明一個(gè)構(gòu)造函數(shù)聲明一個(gè)類以上兩者相比之下,很可以看出,類函數(shù)比構(gòu)造函數(shù),代碼量更少,并且結(jié)構(gòu)層次更加簡(jiǎn)潔明了。類主要內(nèi)容是構(gòu)造函數(shù)靜態(tài)方法繼承。構(gòu)造函數(shù)一個(gè)類里,必有一個(gè)函數(shù),默認(rèn)。
ES6 Class類
ES6中class是基于原型的繼承的語(yǔ)法糖,提供更加清晰的語(yǔ)法來(lái)創(chuàng)建對(duì)象和原型。聲明和定義
es5 聲明一個(gè)構(gòu)造函數(shù):
function Student(name, age) { this.name = name; this.age = age; } Student.prototype.getInfo = function() { return "{name:" + this.name + ",age:" + this.age + "}"; } Student.prototype.setInfo = function(name, age) { this.name = name; this.age = age; } var p = new Student("nico", 1); p.getInfo(); //{name:nico,age:1} p.setInfo("siip", 10); p.getInfo(); //{name:siip,10}
es6 聲明一個(gè)類:
class Student { constructor(name, age) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } let p = new Student("nico", 1); p.setInfo("siip", 10); p.getInfo();//{name:siip,10}
以上兩者相比之下,很可以看出,es6類函數(shù)比es5構(gòu)造函數(shù),代碼量更少,并且結(jié)構(gòu)層次更加簡(jiǎn)潔明了。
有些地方需要注意的是:
es5存在變量提升(var xxx,function xxx(){})
es6不存在變量提升(const,let,class)
Class 方法constructor
constructor是默認(rèn)的方法,就算在聲明類函數(shù)時(shí)沒(méi)有寫(xiě)constructor方法,在實(shí)例化時(shí)會(huì)自動(dòng)添加上一個(gè)空的constructor
class Student { constructor() { this.desc = "test"; } }
通過(guò)babel轉(zhuǎn)碼:
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Student = function Student() { _classCallCheck(this, Student);//類不能直接被調(diào)用,只能通過(guò)new實(shí)例化 this.desc = "test"; };
constructor方法指向自身,在一個(gè)類中只能有一個(gè)名為 “constructor” 的特殊方法。
Student === Student.prototype.constructor;//true
static
簡(jiǎn)述:顧名思義這是一個(gè)靜態(tài)方法,就是不需要實(shí)例化類就可以調(diào)用的方法, 實(shí)例化對(duì)象不能繼承靜態(tài)方法。
class Student { constructor(name, age) { this.name = name; this.age = age; } static ageFilter(...args) { let stuAge = args; let arr = []; for (let i = 0; i < stuAge.length; i++) { if (stuAge[i].age > 12) { arr.push(stuAge[i]) } } return arr; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } Student.ageFilter({ name: "a", age: 1 }, { name: "b", age: 14 });//{name: "a", age: 14}
靜態(tài)函數(shù)的this指向類函數(shù)自身,當(dāng)this沒(méi)有指明被誰(shuí)調(diào)用時(shí),this為undefined
我們將上面代碼用babel編譯,從結(jié)果上看:
var _createClass = function() { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function(Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
從代碼可以看出,靜態(tài)方法與類函數(shù)方法的區(qū)別是:當(dāng)用Object.defineProperty去定義對(duì)象屬性時(shí)傳入的對(duì)象不同,一個(gè)傳入的是構(gòu)造函數(shù)的原型,另一個(gè)是傳入構(gòu)造函數(shù)。
es6當(dāng)前還不支持靜態(tài)屬性
extends
關(guān)鍵字在類聲明或類表達(dá)式中用于創(chuàng)建一個(gè)類作為另一個(gè)類的一個(gè)子類
class Student { constructor(name = null, age = null) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } class Citizen extends Student { constructor(name, age) { super(name, age); this.name = 123; } } let stu = new Citizen("siip", "25"); stu.getInfo(); //{name:siip,age:25}
可以看到子類可以調(diào)用父類上的方法和屬性,當(dāng)使用extends繼承父類時(shí),子類constructor和super和被默認(rèn)添加上,并且在構(gòu)造函數(shù)內(nèi),只有調(diào)用了super函數(shù)后才能使用this,否則會(huì)拋出ReferenceError錯(cuò)誤
constructor() { this.name = "xxx" super() }//ReferenceError
super
super可作為一個(gè)函數(shù)使用
super可作為一個(gè)對(duì)象使用
下面一個(gè)子類繼承父類的Math的方法:
function MathFns() { this.status = "Father" } MathFns.prototype = Math; class Max extends MathFns { constructor() { super(); } static base() { return super.max(); } } let m = new MathFns(); m; //{status: "Father"} m.max(1, 2);//2
我們可以通過(guò)babel編譯,嘗試去理解es6的繼承,
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
這個(gè)封裝繼承函數(shù),主要實(shí)現(xiàn)的功能是,子類原型指向父類,原型構(gòu)造器指向自身,然后再通過(guò)隱式原型鏈指向父類函數(shù),這樣子類被實(shí)例化后的對(duì)像就能使用父類原型鏈上的方法以及通過(guò)隱式原型鏈訪問(wèn)到父類的屬性。
總結(jié)總的來(lái)看,es6的class類實(shí)際上是基于原型鏈和繼承做的一層封裝,它的結(jié)構(gòu)層次相對(duì)于es5原型鏈寫(xiě)法更加清晰明了,代碼量更少。class類主要內(nèi)容是構(gòu)造函數(shù)、靜態(tài)方法、繼承。
構(gòu)造函數(shù)
一個(gè)類里,必有一個(gè)constructor函數(shù),默認(rèn)。
類不存在變量提升
一個(gè)類里只能有一個(gè)constructor函數(shù)
constructor函數(shù)指向類自身
靜態(tài)方法
靜態(tài)函數(shù)的this指向類函數(shù)自身,當(dāng)this沒(méi)有指明被誰(shuí)調(diào)用時(shí),this為undefined
在同一個(gè)類中的一個(gè)靜態(tài)方法調(diào)用另一個(gè)靜態(tài)方法
類實(shí)例化對(duì)象不能調(diào)用類靜態(tài)方法
繼承
子類繼承父類的屬性和方法
在子類繼承父類,子類的構(gòu)造函數(shù)中要先調(diào)用super函數(shù),才能使用this
super可以作為函數(shù)或?qū)ο笳{(diào)用,但指向都是子類
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/107354.html
摘要:的類使用熟悉的關(guān)鍵字指定類繼承的函數(shù),并且可以通過(guò)方法訪問(wèn)父類的構(gòu)造函數(shù)。例如繼承一個(gè)的類繼承了,術(shù)語(yǔ)上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實(shí)例,也是派生類的實(shí)例,內(nèi)建對(duì)象繼承的實(shí)用之處是改變返回對(duì)象的類型。 和其它面向?qū)ο缶幊陶Z(yǔ)言一樣,ES6 正式定義了 class 類以及 extend 繼承語(yǔ)法糖,并且支持靜態(tài)、派生、抽象、迭代、單例等,而且根據(jù) ES6 的新特性衍...
摘要:創(chuàng)建自定義類型看下面一段代碼上面代碼使用創(chuàng)建了一個(gè)自定義類型,是這個(gè)類的構(gòu)造器,是類的公共方法。注意事項(xiàng)在使用類繼承的實(shí)現(xiàn)中,需要注意的點(diǎn)是如果子類沒(méi)有重寫(xiě)方法,默認(rèn)會(huì)調(diào)用父類的構(gòu)造器方法。 es6 類-class 與大多正規(guī)的面向?qū)ο缶幊陶Z(yǔ)言不同(比如java),js在創(chuàng)建之初就不支持類。js的面向?qū)ο缶幊虒?shí)現(xiàn)方式是通過(guò)構(gòu)造函數(shù)和原型來(lái)實(shí)現(xiàn)的。 我之前以為es6引入類的概念將會(huì)帶給這...
摘要:不同于其他面向?qū)ο笳Z(yǔ)言,以前的中中沒(méi)有類的概念,主要是通過(guò)原型的方式來(lái)實(shí)現(xiàn)繼承,中引入了原型鏈,并且將原型鏈用來(lái)實(shí)現(xiàn)繼承,其核心是利用原型使得一個(gè)對(duì)象繼承另一個(gè)對(duì)象的方法和屬性,中原型繼承的關(guān)鍵是將一個(gè)實(shí)例的原型對(duì)象指向另一個(gè)實(shí)例,因此前一 不同于其他面向?qū)ο笳Z(yǔ)言,ES6以前的JavaScript中中沒(méi)有class類的概念,主要是通過(guò)原型的方式來(lái)實(shí)現(xiàn)繼承,JavaScript中引入了原...
摘要:使用類創(chuàng)建實(shí)例對(duì)象也是直接對(duì)類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒(méi)有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有屬性和屬性,因此同時(shí)存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對(duì)象的原型的寫(xiě)法更像面向?qū)ο笳Z(yǔ)言寫(xiě)法。 ES6中通過(guò)class定義對(duì)象,默認(rèn)具有constructor方法和自定義方法,但是包含...
摘要:使用類創(chuàng)建實(shí)例對(duì)象也是直接對(duì)類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒(méi)有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有屬性和屬性,因此同時(shí)存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對(duì)象的原型的寫(xiě)法更像面向?qū)ο笳Z(yǔ)言寫(xiě)法。 ES6中通過(guò)class定義對(duì)象,默認(rèn)具有constructor方法和自定義方法,但是包含...
閱讀 1088·2021-11-22 13:52
閱讀 1509·2021-11-19 09:40
閱讀 3360·2021-11-16 11:44
閱讀 1384·2021-11-15 11:39
閱讀 4049·2021-10-08 10:04
閱讀 5526·2021-09-22 14:57
閱讀 3170·2021-09-10 10:50
閱讀 3263·2021-08-17 10:13