ES6 class -- Class 的方法

来源:https://www.cnblogs.com/chenyingying0/archive/2020/03/27/12582189.html
-Advertisement-
Play Games

靜態方法與靜態屬性 不會被類的實例所擁有,只有類自身擁有的屬性和方法 只能通過類來調用、 static 關鍵字(靜態方法) 類名.屬性名=屬性值(靜態屬性) //車類 class Car{ //構造函數 constructor(wheel,color,length,width){//接收參數 //給 ...


靜態方法與靜態屬性

不會被類的實例所擁有,只有類自身擁有的屬性和方法

只能通過類來調用、

static 關鍵字(靜態方法)

類名.屬性名=屬性值(靜態屬性)

//車類
class Car{
    //構造函數
    constructor(wheel,color,length,width){//接收參數
        //給屬性賦值,this指向當前實例化的結果
        this.wheel=wheel;
        this.color=color;
        this.length=length;
        this.width=width;
        this.speed=0;
    }    

    //方法
    speedUp(){
        this.speed+=1;
    }

    //靜態方法
    static repair(car){
        console.log("我要修車,車是:"+car);
    }
}

//實例化,類->對象
let c=new Car(3,"#abcdef",20,40);
Car.repair("我的蘭博基尼");//調用靜態方法
c.repair("我的蘭博基尼");//實例上沒有靜態方法,無法調用

 

 

普通方法與靜態方法重名,互不影響

//車類
class Car{
    //構造函數
    constructor(wheel,color,length,width){//接收參數
        //給屬性賦值,this指向當前實例化的結果
        this.wheel=wheel;
        this.color=color;
        this.length=length;
        this.width=width;
        this.speed=0;
        this.errors=0;
    }    

    //方法
    speedUp(){
        this.speed+=1;
    }

    //自檢
    checker(){
        console.log("我要自檢");
        //...
        if(this.errors===0){
            console.log("檢測完畢,一切正常");
        }
    }

    //靜態方法
    static checker(car){
        console.log("我要抽查");
    }
}

//實例化,類->對象
let c=new Car(3,"#abcdef",20,40);
Car.checker();//調用靜態方法
c.checker();//調用普通方法

 

 

//車類
class Car{
    //構造函數
    constructor(){//接收參數
        Car.totolCar++;//操作靜態屬性,用來計算被實例化的次數
        //給屬性賦值,this指向當前實例化的結果
        this.speed=0;
        this.errors=0;
    }    

    //方法
    speedUp(){
        this.speed+=1;
    }

    //自檢
    checker(){
        console.log("我要自檢");
        //...
        if(this.errors===0){
            console.log("檢測完畢,一切正常");
        }
    }

    //靜態方法
    static checker(car){
        console.log("我要抽查");
    }
}

//靜態屬性
Car.totolCar=0;

//實例化,類->對象
let c=new Car();
console.log(Car.totolCar);//訪問靜態屬性
new Car();
new Car();
new Car();
Car.checker();//調用靜態方法
c.checker();//調用普通方法
console.log(Car.totolCar);//再次訪問靜態屬性

 

 

靜態屬性可以用來儲存預設配置

 

 

靜態屬性和靜態方法的具體應用場景

//角色類
class Character{
    //構造函數接收參數,實例化時預設會執行
    constructor(pro){
        this.pro=pro;//職業
    }
}

//配置項(靜態屬性)
Character.config={
    //職業映射表
    profession:{
        "咒術師":1,
        "弓箭手":2
    }
}

let c=new Character(Character.config.profession["咒術師"]);

 

 

class Person{
    //靜態方法
    //程式員轉普通人
    static format(programmer){
        programmer.bf=true;
        programmer.hair=true;
    }
}

//程式員類
class Programmer{
    constructor(){
        this.bf=false;//沒有男朋友
        this.hair=false;//沒有頭髮
    }
}

let p=new Programmer();
console.log(p);
Person.format(p);//調用靜態方法
console.log(p);

 

 

類表達式

//函數表達式
const a=function(){

}

//函數聲明
function a2(){

}

//類的聲明
class Myclass{

}

//類表達式
const Myclass2=class{
    constructor(){
        console.log("我是鴿手,咕咕咕");
    }
}

//也可以class後面跟個類名
const Myclass3=class M{
    constructor(){
        console.log(M===Myclass3);//內部可以訪問到
        //作用:如果Myclass3修改了類名,內部的代碼不需要修改,因為用的是內部的類名
        M.a=1;
        console.log("我是鴿手,咕咕咕");
    }
}
//console.log("外部:"+M);//報錯,外部無法訪問到

new Myclass3();

 

 

自執行的類(實際情況基本用不到)

//自執行的類
const Person=new class P{
    constructor(){
        console.log(P);
    }
}();

 

 

getter 與 setter

類似於給屬性提供鉤子,在獲取和設置屬性時做一些額外的事情

 

首先看看ES5中getter和setter,一般有兩種方式

1、在對象字面量中書寫get/set方法

const obj={
    name:"",
    get name(){
        return this.name;
    },
    set name(val){
        this.name=val;
    }    
}
obj.name;

 

這種寫法會造成棧記憶體溢出,因此get name()調用後,return name再次觸發get name() ,無線迴圈

因此需要修改代碼,使get name()和name不同名

const obj={
    _name:"",
    get name(){
        return this._name;
    },
    set name(val){
        this._name=val;
    }    
}
obj.name=222;//調用set name(val)
console.log(obj);
console.log(obj.name);//調用get name()

 

 

2、Object.defineProperty

var obj={
    _name:""
}
Object.defineProperty(obj,"age",{
    value:18
})
console.log(obj);

//遍歷屬性時發現age屬性無法被遍歷
for(var i in obj){
    console.log(i);
}

 

 遍歷屬性時發現age沒有被遍歷,這是因為定義屬性時沒有添加可被枚舉的描述符

添加之後即可被遍歷

var obj={
    _name:""
}
Object.defineProperty(obj,"age",{
    value:18,
    enumerable:true//可被枚舉
})
console.log(obj);

//遍歷屬性時發現age屬性無法被遍歷
for(var i in obj){
    console.log(i);
}

 

 

可以利用此特性為name書寫get和set方法

var obj={
    _name:""
}
Object.defineProperty(obj,"name",{
    get:function(){
        return this._name;
    },
    set:function(val){
        this._name=val;
    }
})

obj.name=10;
console.log(obj.name);

 

 

ES6中使用getter和setter

//ES6中getter和setter
class Person{
    constructor(){
        this._name=""
    }

    get name(){
        return `我的名字是: ${ this._name }`
    }

    set name(val){
        this._name=val
    }
}

const p=new Person();
p.name="cyy";//調用setter
console.log(p.name);//調用getter

 

 

模擬一個小案例:

//ES6中getter和setter的應用
class AudioPlayer{
    constructor(){
        // 0-暫停 | 1-播放 | 2-載入中
        this._status=0
        this.status=0 //使用setter,預設是0
        this.init()
    }

    init(){
        const audio=new Audio()
        audio.src="url"
        audio.canplay=()=>{//如果不使用箭頭函數,則this會指向audio;使用後指向當前對象
            audio.play()
            //使用setter
            this.status=1
        }
    }

    get status(){
        return this._status
    }

    set status(val){
        const STATUS_MAP={
            0:"暫停",
            1:"播放",
            2:"載入中"
        }
        document.querySelector("#app .play-btn").innerText=STATUS_MAP[val]
        this._status=val
    }
}

const a=new AudioPlayer();

 

 

輸入出生年份並自動計算當前年齡的效果

//定義一個類,設置預設的年齡為18
class Age{
    constructor(){
        this._age=18;
    }

    get age(){
        return this._age;
    }

    set age(year){
        //若是設置的年份不是四位數,則採用預設的年齡18
        if(year.length!==4) return;
        this._age=2020-parseInt(year)+1;
    }
}

//使用變數接收輸入的年份
let year=prompt("請輸入出生年份")
//如果獲取到填寫的數據
if (year!=null && year!="")
{
    let a=new Age();
    a.age=year
    document.write("今年的年齡是:"+a.age);
}

 

 

 

 

name屬性與new.target屬性

//name 返回類名
//不常用
class Age{}

console.log(Age.name)

//類的表達式
const Age2=class{}
console.log(Age2.name)

//類的表達式(存在內部類名),則返回內部類名
const Age3=class A{}
console.log(Age3.name)

 

 

//new.target 指向new關鍵字後面的類
//不能直接訪問,必須在類或者類的構造函數中才能訪問

//console.log(new.target)//報錯

class Car{
    constructor(){
        console.log(new.target)
    }
}
new Car()

 

 

new.target 作用
語法糖(Syntactic sugar),也譯為糖衣語法,是由英國電腦科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語

指電腦語言中添加的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式員使用。

通常來說使用語法糖能夠增加程式的可讀性,從而減少程式代碼出錯的機會。

//語法糖:ES5中模擬類的另一種寫法(即下麵這種代碼的語法糖)
function Car(){
    //屬性
    this...
}
//方法
Car.prototype.xxx=function(){

}

 

普通的函數也可以使用new.target

function fn(){
    console.log(new.target)
}
fn()//返回new關鍵字後面的,如果沒有就是undefined
new fn()

 

 

function Fn(){
    if(new.target!==Fn){
        throw("必須使用new關鍵字調用")
    }
}
Fn()//返回new關鍵字後面的,如果沒有就是undefined
new Fn()

 

 

也可以使用instanceof實現相同效果

function Fn(){
    if(!(this instanceof Fn)){
        throw("必須使用new關鍵字調用")
    }
}
Fn()//返回new關鍵字後面的,如果沒有就是undefined
new Fn()

 

 

let Fnn=class Fn{
    constructor(){
        this.name="cyy"
    }
}
let f=new Fnn()
console.log(f.name)//18
console.log(Fnn.name)//Fn

 

 

在ES5中模擬類

 其實js是不支持類的,只是用構造函數模擬類

//ES5中構造函數跟函數一樣
//只是調用時添加了new關鍵字,就會被當做構造函數
//如果沒有返回值,就會返回對象
function Person(name,age){
    this.name=name;
    this.age=age;
}
console.log(new Person("cyy",18));

 

 

用new關鍵字為什麼會返回對象

//用new關鍵字為什麼會返回對象
//1、創建一個空對象
//2、把構造函數的prototype屬性作為空對象的原型
//3、把this賦值為這個空對象
//4、執行函數
//5、如果沒有返回值,就返回this
function Person(name,age){
    this.name=name;
    this.age=age;
}
console.log(new Person("cyy",18));

 

 

自己寫一個函數模擬構造函數的效果

function Constructor(fn,args){
    //1、創建一個空對象
    //2、把構造函數的prototype屬性作為空對象的原型
    var _this=Object.create(fn.prototype);
    //3、把this賦值為這個空對象
    //4、執行函數
    var res=fn.apply(_this,args);
    //5、如果沒有返回值,就返回this
    return res?res:_this;
}


function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.say=function(){
    console.log("我叫"+this.name+",我今年"+this.age+"歲");
}
//把函數變為構造函數
var person=Constructor(Person,["cyy",18]);
console.log(person);//返回一個對象

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如何併發的訪問資料庫呢?答案就是加鎖。 接下來說一下,資料庫的鎖機制,資料庫中都有哪些鎖? 首先呢,鎖是一種併發控制技術,鎖是用來在多個用戶同時訪問同一個數據的時候保護數據的。 有2種基本的鎖類型: 共用(S)鎖:多個事務可封鎖一個共用頁;任何事務都不能修改該頁;通常是該頁被讀取完畢,S鎖立即被釋放 ...
  • 作為 Android 11 開發者預覽版的一部分,Google 已經發佈了 "Android 11 系統鏡像" ,它們能夠執行 ARM 二進位文件,性能得到了顯著提升。 以前,依賴於 ARM 庫而無法構建 x86 變體應用程式的開發人員要麼必須使用具有完全 ARM 模擬的系統映像,這比在基於 x86 ...
  • 在Flutter預設創建的項目中可以使用系統Material圖標,在 文件中使用圖標設置如下: 系統圖標如下: 如果這裡面沒有我們想要的圖標如何處理呢?這時可以使用第三方圖標庫,下麵以 "阿裡巴巴的圖標" 庫為例。 查找圖標並加入購物車 找到自己想要的圖標後,將滑鼠放置到圖標上,加入購物車,如下圖: ...
  • 本文記錄如何讓網頁中的JS代碼和APP進行交互,簡單的說就是如何在網頁中執行APP的代碼。下麵以在網頁中執行代碼打開撥號鍵盤並輸入電話號碼為例介紹如何實現。 一、設置WebView允許它執行js代碼。 二、通過調用WebView的addJavascriptInterface添加一個對象給js使用,添 ...
  • 表格和邊框屬性, 表格表頭單元格,表格標題<caption>,表格高度和寬度,表格背景,表格空間,合併單元格,表格頭部、主體、頁腳,定義表格,定義表格的行,定義表格列的組定義用於表格列的屬性,定義表格的頁眉,定義表格的主體定義表格的頁腳<table><tbody><tr><th>\定義表格的表頭,<... ...
  • 一、繼續完善之前的頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>D188_3DPlayerXia</title> <style> *{ margin:0px; padding:0px; } body{ ...
  • 最近接手了公司兩個項目,一個PC端後臺管理系統,一個app端項目,當然使用的依然是熟悉“Vue全家桶”那套!但是,當我打開項目時,裡面的代碼是這樣的(路由模塊): 就是所有路由配置都放到一個index.js中,這多少還是讓我有點驚呆的,顯然,項目會越做越大,模塊會越加越多,那這種不分模塊的架構方式明 ...
  • ES6中class的繼承 父類(基類) 子類 extends 關鍵字 //父類 class Human{ //父類的構造函數 constructor(name,age,sex,hobby){ this.name=name this.age=age this.sex=sex this.hobby=ho ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...