您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“如何掌握前端JavaScript中的class類”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“如何掌握前端JavaScript中的class類”吧!
類是用于創(chuàng)建對(duì)象的模板。JavaScript
中生成對(duì)象實(shí)例的方法是通過(guò)構(gòu)造函數(shù),這跟主流面向?qū)ο笳Z(yǔ)言(java
,C#
)寫法上差異較大,如下:
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; var p = new Point(1, 1);
ES6
提供了更接近Java
語(yǔ)言的寫法,引入了 Class(類)
這個(gè)概念,作為對(duì)象的模板。通過(guò)class關(guān)鍵字,可以定義類。
如下:constructor()
是構(gòu)造方法,而this代表實(shí)例對(duì)象:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
類的數(shù)據(jù)類型就是函數(shù),它本身就是指向函數(shù)的構(gòu)造函數(shù):
// ES5 函數(shù)聲明 function Point() { //... } // ES6 類聲明 class Point { //.... constructor() { } } typeof Point // "function" Point === Point.prototype.constructor // true
在類里面定義的方法是掛到Point.prototype
,所以類只是提供了語(yǔ)法糖,本質(zhì)還是原型鏈調(diào)用。
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } Point.prototype = { //.... toString() } var p = new Point(1, 1); p.toString() // (1,1)
類的另一種定義方式類表達(dá)式
// 未命名/匿名類 let Point = class { constructor(x, y) { this.x = x; this.y = y; } }; Point.name // Point
函數(shù)聲明和類聲明有個(gè)重要區(qū)別,函數(shù)聲明會(huì)提升,類聲明不會(huì)提升。
> let p = new Point(); // 被提升不會(huì)報(bào)錯(cuò) > function Point() {} > > let p = new Point(); // 報(bào)錯(cuò),ReferenceError > class Point {} >
constructor()
方法是類的默認(rèn)方法,new
生成實(shí)例對(duì)象時(shí)會(huì)自動(dòng)調(diào)用該方法。
一個(gè)類必須有constructor()
方法,如果沒(méi)有顯式定義,引擎會(huì)默認(rèn)添加一個(gè)空的constructor()
。
constructor()
方法默認(rèn)返回實(shí)例對(duì)象(即this
)。
class Point { } // 自動(dòng)添加 class Point { constructor() {} }
與 ES5
一樣,在類的內(nèi)部可以使用get
和set
關(guān)鍵字,對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為。
class User { constructor(name) { this.name = name; } get name() { return this.name; } set name(value) { this.name = value; } }
類的方法內(nèi)部的this
,它默認(rèn)指向類的實(shí)例,在調(diào)用存在this的方法時(shí),需要使用 obj.method()
方式,否則會(huì)報(bào)錯(cuò)。
class User { constructor(name) { this.name = name; } printName(){ console.log('Name is ' + this.name) } } const user = new User('jack') user.printName() // Name is jack const { printName } = user; printName() // 報(bào)錯(cuò) Cannot read properties of undefined (reading 'name')
如果要單獨(dú)調(diào)用又不報(bào)錯(cuò),一種方法可以在構(gòu)造方法里調(diào)用bind(this)
。
class User { constructor(name) { this.name = name; this.printName = this.printName.bind(this); } printName(){ console.log('Name is ' + this.name) } } const user = new User('jack') const { printName } = user; printName() // Name is jack
bind(this)
會(huì)創(chuàng)建一個(gè)新函數(shù),并將傳入的this作為該函數(shù)在調(diào)用時(shí)上下文指向。
另外可以使用箭頭函數(shù),因?yàn)榧^函數(shù)內(nèi)部的this總是指向定義時(shí)所在的對(duì)象。
class User { constructor(name) { this.name = name; } printName = () => { console.log('Name is ' + this.name) } } const user = new User('jack') const { printName } = user; printName() // Name is jack
靜態(tài)屬性指的是類本身的屬性,而不是定義在實(shí)例對(duì)象this
上的屬性。
class User { } User.prop = 1; User.prop // 1
可以在類里面定義靜態(tài)方法,該方法不會(huì)被對(duì)象實(shí)例繼承,而是直接通過(guò)類來(lái)調(diào)用。
靜態(tài)方法里使用this
是指向類。
class Utils { static printInfo() { this.info(); } static info() { console.log('hello'); } } Utils.printInfo() // hello
關(guān)于方法的調(diào)用范圍限制,比如:私有公有,ES6
暫時(shí)沒(méi)有提供,一般是通過(guò)約定,比如:在方法前面加下劃線_print()表示私有方法。
Java
中通過(guò)extends
實(shí)現(xiàn)類的繼承。ES6
中類也可以通過(guò)extends
實(shí)現(xiàn)繼承。
繼承時(shí),子類必須在constructor
方法中調(diào)用super
方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)。
class Point3D extends Point { constructor(x, y, z) { super(x, y); // 調(diào)用父類的constructor(x, y) this.z = z; } toString() { return super.toString() + ' ' + this.z ; // 調(diào)用父類的toString() } }
父類的靜態(tài)方法,也會(huì)被子類繼承
class Parent { static info() { console.log('hello world'); } } class Child extends Parent { } Child.info() // hello world
在子類的構(gòu)造函數(shù)必須執(zhí)行一次super
函數(shù),它代表了父類的構(gòu)造函數(shù)。
class Parent {} class Child extends Parent { constructor() { super(); } }
在子類普通方法中通過(guò)super
調(diào)用父類的方法時(shí),方法內(nèi)部的this
指向當(dāng)前的子類實(shí)例。
class Parent { constructor() { this.x = 1; this.y = 10 } printParent() { console.log(this.y); } print() { console.log(this.x); } } class Child extends Parent { constructor() { super(); this.x = 2; } m() { super.print(); } } let c = new Child(); c.printParent() // 10 c.m() // 2
初學(xué)JavaScript
時(shí), _proto_
和prototype
很容易混淆。首先我們知道每個(gè)JS
對(duì)象都會(huì)對(duì)應(yīng)一個(gè)原型對(duì)象,并從原型對(duì)象繼承屬性和方法。
prototype
一些內(nèi)置對(duì)象和函數(shù)的屬性,它是一個(gè)指針,指向一個(gè)對(duì)象,這個(gè)對(duì)象的用途就是包含所有實(shí)例共享的屬性和方法(我們把這個(gè)對(duì)象叫做原型對(duì)象)。
_proto_
每個(gè)對(duì)象都有這個(gè)屬性,一般指向?qū)?yīng)的構(gòu)造函數(shù)的prototype
屬性。
下圖是一些擁有prototype內(nèi)置對(duì)象:
根據(jù)上面描述,看下面代碼
var obj = {} // 等同于 var obj = new Object() // obj.__proto__指向Object構(gòu)造函數(shù)的prototype obj.__proto__ === Object.prototype // true // obj.toString 調(diào)用方法從Object.prototype繼承 obj.toString === obj.__proto__.toString // true // 數(shù)組 var arr = [] arr.__proto__ === Array.prototype // true
對(duì)于function
對(duì)象,聲明的每個(gè)function
同時(shí)擁有prototype
和__proto__
屬性,創(chuàng)建的對(duì)象屬性__proto__
指向函數(shù)prototype
,函數(shù)的__proto__
又指向內(nèi)置函數(shù)對(duì)象(Function)的prototype
。
function Foo(){} var f = new Foo(); f.__proto__ === Foo.prototype // true Foo.__proto__ === Function.prototype // true
類作為構(gòu)造函數(shù)的語(yǔ)法糖,也會(huì)同時(shí)有prototype
屬性和__proto__
屬性,因此同時(shí)存在兩條繼承鏈。
子類的__proto__
屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。
子類prototype屬性的__proto__
屬性,表示方法的繼承,總是指向父類的prototype
屬性。
class Parent { } class Child extends Parent { } Child.__proto__ === Parent // true Child.prototype.__proto__ === Parent.prototype // true
子類實(shí)例的__proto__
屬性,指向子類構(gòu)造方法的prototype
。
子類實(shí)例的__proto__
屬性的__proto__
屬性,指向父類實(shí)例的__proto__
屬性。也就是說(shuō),子類的原型的原型,是父類的原型。
class Parent { } class Child extends Parent { } var p = new Parent(); var c = new Child(); c.__proto__ === p.__proto__ // false c.__proto__ === Child.prototype // true c.__proto__.__proto__ === p.__proto__ // true
到此,相信大家對(duì)“如何掌握前端JavaScript中的class類”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。