摘要:聲明和定義聲明一個構造函數聲明一個類以上兩者相比之下,很可以看出,類函數比構造函數,代碼量更少,并且結構層次更加簡潔明了。類主要內容是構造函數靜態方法繼承。構造函數一個類里,必有一個函數,默認。
ES6 Class類
ES6中class是基于原型的繼承的語法糖,提供更加清晰的語法來創建對象和原型。聲明和定義
es5 聲明一個構造函數:
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類函數比es5構造函數,代碼量更少,并且結構層次更加簡潔明了。
有些地方需要注意的是:
es5存在變量提升(var xxx,function xxx(){})
es6不存在變量提升(const,let,class)
Class 方法constructor
constructor是默認的方法,就算在聲明類函數時沒有寫constructor方法,在實例化時會自動添加上一個空的constructor
class Student { constructor() { this.desc = "test"; } }
通過babel轉碼:
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);//類不能直接被調用,只能通過new實例化 this.desc = "test"; };
constructor方法指向自身,在一個類中只能有一個名為 “constructor” 的特殊方法。
Student === Student.prototype.constructor;//true
static
簡述:顧名思義這是一個靜態方法,就是不需要實例化類就可以調用的方法, 實例化對象不能繼承靜態方法。
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}
靜態函數的this指向類函數自身,當this沒有指明被誰調用時,this為undefined
我們將上面代碼用babel編譯,從結果上看:
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; }; }();
從代碼可以看出,靜態方法與類函數方法的區別是:當用Object.defineProperty去定義對象屬性時傳入的對象不同,一個傳入的是構造函數的原型,另一個是傳入構造函數。
es6當前還不支持靜態屬性
extends
關鍵字在類聲明或類表達式中用于創建一個類作為另一個類的一個子類
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}
可以看到子類可以調用父類上的方法和屬性,當使用extends繼承父類時,子類constructor和super和被默認添加上,并且在構造函數內,只有調用了super函數后才能使用this,否則會拋出ReferenceError錯誤
constructor() { this.name = "xxx" super() }//ReferenceError
super
super可作為一個函數使用
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; }
這個封裝繼承函數,主要實現的功能是,子類原型指向父類,原型構造器指向自身,然后再通過隱式原型鏈指向父類函數,這樣子類被實例化后的對像就能使用父類原型鏈上的方法以及通過隱式原型鏈訪問到父類的屬性。
總結總的來看,es6的class類實際上是基于原型鏈和繼承做的一層封裝,它的結構層次相對于es5原型鏈寫法更加清晰明了,代碼量更少。class類主要內容是構造函數、靜態方法、繼承。
構造函數
一個類里,必有一個constructor函數,默認。
類不存在變量提升
一個類里只能有一個constructor函數
constructor函數指向類自身
靜態方法
靜態函數的this指向類函數自身,當this沒有指明被誰調用時,this為undefined
在同一個類中的一個靜態方法調用另一個靜態方法
類實例化對象不能調用類靜態方法
繼承
子類繼承父類的屬性和方法
在子類繼承父類,子類的構造函數中要先調用super函數,才能使用this
super可以作為函數或對象調用,但指向都是子類
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107354.html
摘要:的類使用熟悉的關鍵字指定類繼承的函數,并且可以通過方法訪問父類的構造函數。例如繼承一個的類繼承了,術語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內建對象繼承的實用之處是改變返回對象的類型。 和其它面向對象編程語言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態、派生、抽象、迭代、單例等,而且根據 ES6 的新特性衍...
摘要:不同于其他面向對象語言,以前的中中沒有類的概念,主要是通過原型的方式來實現繼承,中引入了原型鏈,并且將原型鏈用來實現繼承,其核心是利用原型使得一個對象繼承另一個對象的方法和屬性,中原型繼承的關鍵是將一個實例的原型對象指向另一個實例,因此前一 不同于其他面向對象語言,ES6以前的JavaScript中中沒有class類的概念,主要是通過原型的方式來實現繼承,JavaScript中引入了原...
摘要:使用類創建實例對象也是直接對類使用命令,跟中構造函數的用法一致。中沒有構造函數,作為構造函數的語法糖,同時有屬性和屬性,因此同時存在兩條繼承鏈。子類的屬性,表示構造函數的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對象的原型的寫法更像面向對象語言寫法。 ES6中通過class定義對象,默認具有constructor方法和自定義方法,但是包含...
摘要:使用類創建實例對象也是直接對類使用命令,跟中構造函數的用法一致。中沒有構造函數,作為構造函數的語法糖,同時有屬性和屬性,因此同時存在兩條繼承鏈。子類的屬性,表示構造函數的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對象的原型的寫法更像面向對象語言寫法。 ES6中通過class定義對象,默認具有constructor方法和自定義方法,但是包含...
閱讀 1008·2021-11-22 13:52
閱讀 1445·2021-11-19 09:40
閱讀 3162·2021-11-16 11:44
閱讀 1272·2021-11-15 11:39
閱讀 3902·2021-10-08 10:04
閱讀 5362·2021-09-22 14:57
閱讀 3101·2021-09-10 10:50
閱讀 3184·2021-08-17 10:13