摘要:聲明和定義聲明一個構(gòu)造函數(shù)聲明一個類以上兩者相比之下,很可以看出,類函數(shù)比構(gòu)造函數(shù),代碼量更少,并且結(jié)構(gòu)層次更加簡潔明了。類主要內(nèi)容是構(gòu)造函數(shù)靜態(tài)方法繼承。構(gòu)造函數(shù)一個類里,必有一個函數(shù),默認。
ES6 Class類
ES6中class是基于原型的繼承的語法糖,提供更加清晰的語法來創(chuàng)建對象和原型。聲明和定義
es5 聲明一個構(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 聲明一個類:
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)層次更加簡潔明了。
有些地方需要注意的是:
es5存在變量提升(var xxx,function xxx(){})
es6不存在變量提升(const,let,class)
Class 方法constructor
constructor是默認的方法,就算在聲明類函數(shù)時沒有寫constructor方法,在實例化時會自動添加上一個空的constructor
class Student { constructor() { this.desc = "test"; } }
通過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)用,只能通過new實例化 this.desc = "test"; };
constructor方法指向自身,在一個類中只能有一個名為 “constructor” 的特殊方法。
Student === Student.prototype.constructor;//true
static
簡述:顧名思義這是一個靜態(tài)方法,就是不需要實例化類就可以調(diào)用的方法, 實例化對象不能繼承靜態(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沒有指明被誰調(diào)用時,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去定義對象屬性時傳入的對象不同,一個傳入的是構(gòu)造函數(shù)的原型,另一個是傳入構(gòu)造函數(shù)。
es6當(dāng)前還不支持靜態(tài)屬性
extends
關(guān)鍵字在類聲明或類表達式中用于創(chuàng)建一個類作為另一個類的一個子類
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繼承父類時,子類constructor和super和被默認添加上,并且在構(gòu)造函數(shù)內(nèi),只有調(diào)用了super函數(shù)后才能使用this,否則會拋出ReferenceError錯誤
constructor() { this.name = "xxx" super() }//ReferenceError
super
super可作為一個函數(shù)使用
super可作為一個對象使用
下面一個子類繼承父類的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
我們可以通過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; }
這個封裝繼承函數(shù),主要實現(xiàn)的功能是,子類原型指向父類,原型構(gòu)造器指向自身,然后再通過隱式原型鏈指向父類函數(shù),這樣子類被實例化后的對像就能使用父類原型鏈上的方法以及通過隱式原型鏈訪問到父類的屬性。
總結(jié)總的來看,es6的class類實際上是基于原型鏈和繼承做的一層封裝,它的結(jié)構(gòu)層次相對于es5原型鏈寫法更加清晰明了,代碼量更少。class類主要內(nèi)容是構(gòu)造函數(shù)、靜態(tài)方法、繼承。
構(gòu)造函數(shù)
一個類里,必有一個constructor函數(shù),默認。
類不存在變量提升
一個類里只能有一個constructor函數(shù)
constructor函數(shù)指向類自身
靜態(tài)方法
靜態(tài)函數(shù)的this指向類函數(shù)自身,當(dāng)this沒有指明被誰調(diào)用時,this為undefined
在同一個類中的一個靜態(tài)方法調(diào)用另一個靜態(tài)方法
類實例化對象不能調(diào)用類靜態(tài)方法
繼承
子類繼承父類的屬性和方法
在子類繼承父類,子類的構(gòu)造函數(shù)中要先調(diào)用super函數(shù),才能使用this
super可以作為函數(shù)或?qū)ο笳{(diào)用,但指向都是子類
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107354.html
摘要:的類使用熟悉的關(guān)鍵字指定類繼承的函數(shù),并且可以通過方法訪問父類的構(gòu)造函數(shù)。例如繼承一個的類繼承了,術(shù)語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內(nèi)建對象繼承的實用之處是改變返回對象的類型。 和其它面向?qū)ο缶幊陶Z言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態(tài)、派生、抽象、迭代、單例等,而且根據(jù) ES6 的新特性衍...
摘要:創(chuàng)建自定義類型看下面一段代碼上面代碼使用創(chuàng)建了一個自定義類型,是這個類的構(gòu)造器,是類的公共方法。注意事項在使用類繼承的實現(xiàn)中,需要注意的點是如果子類沒有重寫方法,默認會調(diào)用父類的構(gòu)造器方法。 es6 類-class 與大多正規(guī)的面向?qū)ο缶幊陶Z言不同(比如java),js在創(chuàng)建之初就不支持類。js的面向?qū)ο缶幊虒崿F(xiàn)方式是通過構(gòu)造函數(shù)和原型來實現(xiàn)的。 我之前以為es6引入類的概念將會帶給這...
摘要:不同于其他面向?qū)ο笳Z言,以前的中中沒有類的概念,主要是通過原型的方式來實現(xiàn)繼承,中引入了原型鏈,并且將原型鏈用來實現(xiàn)繼承,其核心是利用原型使得一個對象繼承另一個對象的方法和屬性,中原型繼承的關(guān)鍵是將一個實例的原型對象指向另一個實例,因此前一 不同于其他面向?qū)ο笳Z言,ES6以前的JavaScript中中沒有class類的概念,主要是通過原型的方式來實現(xiàn)繼承,JavaScript中引入了原...
摘要:使用類創(chuàng)建實例對象也是直接對類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語法糖,同時有屬性和屬性,因此同時存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對象的原型的寫法更像面向?qū)ο笳Z言寫法。 ES6中通過class定義對象,默認具有constructor方法和自定義方法,但是包含...
摘要:使用類創(chuàng)建實例對象也是直接對類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語法糖,同時有屬性和屬性,因此同時存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對象的原型的寫法更像面向?qū)ο笳Z言寫法。 ES6中通過class定義對象,默認具有constructor方法和自定義方法,但是包含...
閱讀 1020·2021-11-22 13:52
閱讀 1450·2021-11-19 09:40
閱讀 3185·2021-11-16 11:44
閱讀 1279·2021-11-15 11:39
閱讀 3914·2021-10-08 10:04
閱讀 5374·2021-09-22 14:57
閱讀 3108·2021-09-10 10:50
閱讀 3191·2021-08-17 10:13