es6新特性之 class 基本用法解析
javaScript 語言中,生成實(shí)例對(duì)象的傳統(tǒng)方法是通過構(gòu)造函數(shù),與傳統(tǒng)的面向?qū)ο笳Z言(比如 C++ 和 Java)差異很大,ES6 提供了更接近傳統(tǒng)語言的寫法,引入了 class(類)這個(gè)概念,作為對(duì)象的模板。通過class關(guān)鍵字,可以定義類。
es6 class 與es5的面向?qū)ο蟮膮^(qū)別:
1. 寫法不同,使用關(guān)鍵字class
2.當(dāng)new一個(gè)實(shí)例,默認(rèn)有一個(gè)constructor方法,且默認(rèn)返回實(shí)例對(duì)象(this),也可以返回另一對(duì)象
3.類的所有方法都在prototype屬性上,但是不可枚舉,且每方法結(jié)束不能使用分號(hào)
4.類的調(diào)用必須通過new 一個(gè)實(shí)例,且類的內(nèi)部默認(rèn)使用嚴(yán)格模式
5.不存在變量提升,必須先聲明,再調(diào)用
6.class的this 默認(rèn)指向當(dāng)前類
7.class 的靜態(tài)方法,使用關(guān)鍵字static,不需new,直接通過類來調(diào)用
8. 實(shí)例屬性和靜態(tài)屬性的寫法,實(shí)例屬性在類的內(nèi)部直接使用等式(=)寫法,也可以寫在constructor 方法里,靜態(tài)屬性只需在實(shí)例屬性前加一個(gè)關(guān)鍵字static即可
9.類的繼承使用關(guān)鍵字extends,繼承機(jī)制與es5完全不同,
es5的繼承原理:先new子類的實(shí)例對(duì)象this,再通過將父類的方法和屬性添加到子類的this上(parents.call(this))。
Es6的繼承原理:先創(chuàng)造父類的實(shí)例對(duì)象this,所以要構(gòu)造函數(shù)constructor()訪問父類的屬性使用this,必須先調(diào)用super()方法;再通過子類的constructor()來修改this
10.類的繼承可以繼承原生的構(gòu)造函數(shù),es5不可以
1. 一般寫法(es5 與es6)
//一.ES5寫法:
function Animate(name){
this.name = name;
}
Animate.prototype.getname = function(){
console.log(this.name)
}
var p =new Animate("lity");
p.getname();
//二.ES6,面向?qū)ο蟮膶懛?calss,
class Person{
//constructor():構(gòu)造方法是默認(rèn)方法,new的時(shí)候回自動(dòng)調(diào)用,如果沒有顯式定義,會(huì)自動(dòng)添加
//1.適合做初始化數(shù)據(jù)
//2.constructor可以指定返回的對(duì)象
constructor(name,age){
this.name = name;
this.age = age;
}
getval(){
console.log(`你是${this.name},${this.age}歲`);
}
}
var c1 = new Person("lity",20);
c1.getval();
ES6 的class可以看作只是一個(gè)語法糖,它的絕大部分功能,ES5 都可以做到
注意 :class 類的本質(zhì)還是一個(gè)函數(shù),類本身就指向構(gòu)造函數(shù)。
typeof Person //function Person === Person.prototype.constructor // true
我們使用Object的一些屬性或者方法檢測一下 用es6 寫的實(shí)例對(duì)象
//1.查看實(shí)例對(duì)象c1的__proto__是否指向Person的原型(Person.prototype)
console.log(c1.__proto__==Person.prototype)//true
console.log(c1.__proto__)//原型對(duì)象的所有方法
//2.isPrototypeOf:檢測實(shí)例對(duì)象是否是某個(gè)函數(shù)的原型
console.log(Person.prototype.isPrototypeOf(c1));//true
//3.constructor:查看某個(gè)對(duì)象的構(gòu)造函數(shù)
console.log(c1.constructor);
//4.hasOwnProperty:檢測某個(gè)屬性是否是自己的屬性;不是原型對(duì)象上的屬性和方法
console.log(c1.hasOwnProperty("name"))//true;
//5.in:通過in可以檢測屬性是否在自己中(this)或者是原型中存在
console.log("getval" in c1)//原型上存在,true
console.log("name" in c1)//constructor(自己上存在),true
//6.自定義檢測屬性是否是存在
function hasproperty(attr,obj){
return obj.hasOwnProperty(attr)&&(attr in obj);
}
console.log(hasproperty("name",c1));//true;
2.表達(dá)式寫法
//class表達(dá)式
const Myclass = class Me{//這里的Me是沒有作用的
constructor(name,jog){
this.name = name;
this.jog = jog;
}
getval(){
console.log(`name is ${this.name},job is a ${this.jog}`);
}
}
var obj1 = new Myclass("lylt","teacher");
obj1.getval();
3.class的私有方法(ES6不提供寫法)和私有屬性(也不提供寫法,提案用#識(shí)別)
所謂私有方法和私有屬性,是指只能在類的內(nèi)部使用,不能在類外部調(diào)用
4.ES6規(guī)定Class類沒有靜態(tài)屬性,只有靜態(tài)方法:static
所謂靜態(tài),不需要實(shí)例化對(duì)象,直接調(diào)用
class Foo {
static classMethod() {
return 'lity';
}
}
console.log(Foo.classMethod()) // 'hello'
5.new.target屬性
new是在構(gòu)造函數(shù)生成實(shí)例的命令,ES6為new提供了一個(gè)屬性.target,
返回通過new 命令實(shí)例對(duì)象的class(構(gòu)造函數(shù)),一般用于類的內(nèi)部
//ES5:原始寫法對(duì)象
function objtarge(name){
if(new.target==undefined){
throw new Error("必須實(shí)例化對(duì)象");
}else{
this.name = name
}
}
var targets = new objtarge("litys");
console.log(targets.name);//litys
//es6寫法:class內(nèi)部使用new.target,返回當(dāng)前的calss
class caltartget{
constructor(name){
console.log(new.target==caltartget);//true
if(new.target!==caltartget){
throw new Error("實(shí)例化對(duì)象不是caltrget");
}else{
this.name = name;
}
}
}
var caltart = new caltartget("lity");
console.log(caltart.name);//lity
6.this指向
類的方法內(nèi)部如果含有this,它默認(rèn)指向類的實(shí)例。但是,必須非常小心,一旦單獨(dú)使用該方法,很可能報(bào)錯(cuò)
如下示例
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
分析以上示例:prinName 的方法中this,默認(rèn)指向 類Logger,但是將改方法單獨(dú)調(diào)用,就會(huì)報(bào)錯(cuò),this會(huì)指向所在運(yùn)行的環(huán)境,所以因?yàn)檎也坏絫his.print()方法而報(bào)錯(cuò)。
針對(duì)以上解決this指向的方法:
(1). 使用bind(this)
(2). 使用es6 的箭頭函數(shù) ()=>{}
(3).使用Proxy 代理
//1.bind()方法
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
//2.箭頭函數(shù) ()=>{}
class Logger {
constructor() {
this.printName = (name = 'there') => {
this.print(`Hello ${name}`);
};
}
// ...
}
//3. Porxy()
.................
7.class 的get() 和set() 方法
與 ES5 一樣,在“類”的內(nèi)部可以使用get和set關(guān)鍵字,對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù),攔截該屬性的存取行為。
class MyClass {
constructor() {
// ...
}
get prop() {// 使用 get 攔截了該方法的返回值
return 'getter';
}
set prop(value) {//當(dāng)對(duì)該方法賦值時(shí)能獲取到該賦值
console.log('setter: '+value);
}
}
let obj = new MyClass();
obj.prop = 123;
// setter: 123
inst.prop
// 'getter'
8.繼承
Class 可以通過extends關(guān)鍵字實(shí)現(xiàn)繼承,這比 ES5 的通過修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多。
//es5 的繼承
//父類
function Person(name,sex){
this.name = name;//屬性
this.sex = sex;//屬性
}
//定義一個(gè)原型方法
Person.prototype.show = function(){
console.log("我的姓名是"+this.name+"==="+"我的性別是"+this.sex)
}
//子類
function Worker(name,sex,job){
//構(gòu)成函數(shù)偽裝:使用call()方法綁定this,偽裝繼承父級(jí)的屬性
Person.call(this,name,sex);
this.job = job;
}
//繼承父類的原型方法:(介紹三種方法)
//寫法一:通過遍歷父級(jí)的原型一個(gè)個(gè)賦給子級(jí)的原型(es5 的原型是可枚舉的,es6的不可以枚舉)
(var i in Person.prototype){
Worker.prototype[i] = Person.prototype[i];
}
//寫法:重新new一個(gè)父級(jí)對(duì)象賦給子級(jí)的原型
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;
//寫法三:創(chuàng)建一個(gè)原型對(duì)象賦給子級(jí)的原型;(es5 推薦)
Worker.prototype = Object.create(Person.prototype);
Worker.prototype.constructor = Worker;
var workers = new Worker("小明","男","job")
//es6 的繼承
class Person{
constructor(name,sex){
this.name = name;//屬性
this.sex = sex;//屬性
}
}
class Worker extends Person{
constructor(name,sex,job){
super();
this.job =job;
}
}
var workers = new Worker("小明","男","job")
8.1:super關(guān)鍵字:在子類中不同情況用法不同,既可以當(dāng)作函數(shù)使用,也可以當(dāng)作對(duì)象使用。
(1):super作為函數(shù),只能在constructor中使用:代表父類,返回子類的this
(2):super作為對(duì)象,在普通函數(shù)中,cuper指向父類的原型對(duì)象,可以訪問原型對(duì)象的屬性和方法,注意,父類的實(shí)例的屬性和方法是訪問不了的
(3):super作為對(duì)象,在靜態(tài)方法中,cuper指向的是父類,不是父類的原型對(duì)象
示例分析如下:
//父類
class Aniamte{
constructor(){
if(new.target == Aniamte){
throw new Error("本類不能實(shí)例化,只能有子類繼承");
}
}
//靜態(tài)方法
static getval(mgs){
console.log("父類的static",mgs)
}
//普通方法
setname(){
console.log("該方法有子類重寫")
}
}
//子類
class Dog extends Aniamte{
constructor(){
super();//調(diào)用此方法,this才用可以用,代表父類的構(gòu)造函數(shù),返回的卻是子類
//super() ==父類.prototype.constructor.call(子類/this)
console.log(this)//Dog {}
this.age = 20;
}
//靜態(tài)方法,super在靜態(tài)方法中作為對(duì)象使用,指向父類;
static getval(mgs){
super.getval(mgs)//父類的static niceday
console.log("子類的static",mgs)//子類的static niceday
}
setname(name){
//普通方法,super作為對(duì)象使用,指向父類的原型對(duì)象,父類.prototype;
super.setname();//該方法有子類重寫
this.name = name;
return this.name
}
};
Dog.getval("niceday");//靜態(tài)方法,直接調(diào)用
//var parAni = new Aniamte();//報(bào)錯(cuò)
var dogs = new Dog();//new 一個(gè)示例對(duì)象
dogs.setname("DOYS");////DOYS
8.2.原生構(gòu)造函數(shù)的繼承,ES5不支持,ES6利用extend可以繼承原生構(gòu)造函數(shù)
//ESMAScript的構(gòu)造函數(shù)有以下幾種
/* Boolean()
* Unmber()
* String()
* Array()
* Date()
* Function()
* RegExp()
* Error()
* Object()
*/
//實(shí)例一:自定義類Myarray 繼承了原生的數(shù)組的構(gòu)造函數(shù),擁有原生數(shù)組的屬性和方法了
class Myarray extends Array{
constructor(){
super();
console.log(this.constructor.name)//Myarray
}
}
var myarr = new Myarray();
console.log(Object.prototype.toString.call(myarr));//[object Array]
myarr.push(1,2,1);
console.log(myarr.length)//3
總結(jié)
以上所述是小編給大家介紹的es6新特性之 class 基本用法解析,希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
- ES6中非常實(shí)用的新特性介紹
- JavaScript ES6的新特性使用新方法定義Class
- JavaScript中的Reflect對(duì)象詳解(ES6新特性)
- 深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù)
- 簡單談?wù)凟S6的六個(gè)小特性
- ES6新特性之Symbol類型用法分析
- ES6(ECMAScript 6)新特性之模板字符串用法分析
- ES6新特性之變量和字符串用法示例
- ES6新特性之模塊Module用法詳解
- ES6新特性之字符串的擴(kuò)展實(shí)例分析
- ES6新特性二:Iterator(遍歷器)和for-of循環(huán)詳解
- ES6新特性六:promise對(duì)象實(shí)例詳解
- ES6新特性七:數(shù)組的擴(kuò)充詳解
- ES6新特性八:async函數(shù)用法實(shí)例詳解
- ES6新特性之類(Class)和繼承(Extends)相關(guān)概念與用法分析
- 讓微信小程序支持ES6中Promise特性的方法詳解
- ES6新特性:使用export和import實(shí)現(xiàn)模塊化詳解
- ES6 13個(gè)新特性總結(jié)
相關(guān)文章
JavaScript數(shù)組對(duì)象實(shí)現(xiàn)增加一個(gè)返回隨機(jī)元素的方法
這篇文章主要介紹了JavaScript數(shù)組對(duì)象實(shí)現(xiàn)增加一個(gè)返回隨機(jī)元素的方法,涉及javascript針對(duì)數(shù)組及隨機(jī)數(shù)的相關(guān)操作技巧,需要的朋友可以參考下2015-07-07
詳解小程序如何改變onLoad的執(zhí)行時(shí)機(jī)
這篇文章主要介紹了詳解小程序如何改變onLoad的執(zhí)行時(shí)機(jī),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
基于JavaScript+IntersectionObserver實(shí)現(xiàn)高性能圖片懶加載
在 Web 開發(fā)中,圖片懶加載是一種常見的優(yōu)化手段,尤其在長列表頁面中,按需加載圖片可以顯著提升頁面性能,本篇文章將通過 JavaScript 和 Intersection Observer,實(shí)現(xiàn)一個(gè)帶有卡片樣式的高性能圖片懶加載示例,需要的朋友可以參考下2025-01-01
判斷目標(biāo)是否是window,document,和擁有tagName的Element的代碼
判斷目標(biāo)是否是window,document,和擁有tagName的Element的代碼,需要的朋友可以參考下。2010-05-05

