中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ES6 class 類的理解(一)

發布時間:2020-06-18 23:49:14 來源:網絡 閱讀:279 作者:易函123 欄目:web開發

優點

ES6 的類提供了幾點明顯的好處:

兼容當前大量的代碼。
相對于構造器和構造器繼承,類使初學者更容易入門。
子類化在語言層面支持。
可以子類化內置的構造器。
不再需要繼承庫;框架之間的代碼變得更加輕便。
為將來的高級特性奠定了基礎: traits (或者 mixins ), 不可變實例,等等。
使工具能夠靜態分析代碼( IDE ,類型檢測器,代碼風格檢測器,等等)。

缺點

ES6 類掩蓋了 JavaScript 繼承的本質;
類會禁錮你,因為強制性的 new。

傳統的類

function Point(x, y){
    this.x = x;
    this.y = y;
}
Point.prototype.toString = function(){
    return "(" + this.x + "," + this.y + ")";
}
const p = new Point(1,2);
console.log(p);//Point {x: 1, y: 2}
console.log(p.toString());//(1,2)

ES6的class寫法就相當于語法糖

上面代碼的改用class來寫

class Points {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString(){
        return '(' + this.x + ',' + this.y + ')';            }
}
const ps = new Points(1, 2);
console.log(ps);//Points {x: 1, y: 2}
console.log(ps.toString());//(1,2)

ES6的類可以看作構造函數的另一種寫法

class Cty{
    //....
}
console.log(typeof Cty);//function
console.log(Cty === Cty.prototype.constructor);//true
//類的數據類型是函數,類本身就指向構造函數

使用的時候,也是直接對類使用new命令,跟構造函數的用法完全一致

class Bar {
    doStuff(){
        console.log('stuff');
    }
}
const b =new Bar();
b.doStuff();//stuff

類的實例上面的方法,其實就是調用原型上的方法

class B {};
const BS = new B();
console.log(BS.constructor === B.prototype.constructor);//true

類與子類

class Poin{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    toString(){
        return `(${this.x},${this.y})`;
    }
}
class ColorPoin extends Poin{
    constructor(x,y,color){
        super(x,y);
        this.color = color;
    }
    toString(){
        return super.toString() + " in " + this. color;
    }
}
// 類型
console.log(typeof Poin);//function
//news實例
const cp = new ColorPoin(25,8,'green');
console.log(cp.toString());//(25,8) in green
console.log(cp instanceof ColorPoin);//true
console.log(cp instanceof Poin);//true
// instanceof測試構造函數的prototype屬性是否出現在對象的原型鏈中的任何位置

下面是一些方法:

Object.assign方法可以很方便的一次像類添加多個方法

class ObjAssign {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
}
Object.assign(ObjAssign.prototype,{
    toString(){
        console.log("string");
    },
    toValue(){
        console.log("value")
        }
})
const Obj = new ObjAssign('Bob',24);
console.log(Obj);
Obj.toString();//string
Obj.toValue();//value
console.log(Object.keys(ObjAssign.prototype));//["toString", "toValue"]
console.log(Object.getOwnPropertyNames(ObjAssign.prototype));// ["constructor", "toString", "toValue"]

類的實例

 class Pott {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    toString() {
        return '(' + this.x + ',' + this.y + ')';
    }
}
const pott = new Pott(2,3);
pott.toString();
console.log(pott.hasOwnProperty("x"));//true
console.log(pott.hasOwnProperty("y"));//true
console.log(pott.hasOwnProperty("toString"));//false
console.log(pott);
console.log(pott.__proto__);
console.log(pott.__proto__.hasOwnProperty("toString"));//true

const p1 = new Pott(2,3);
const p2 = new Pott(3,3);

console.log(p1.__proto__ === p2.__proto__);//true

p1.__proto__.printName = function(){
    return "Oops";
}
console.log(p1.printName());//Oops
console.log(p2.printName());//Oops
const p3 = new Pott(4,2);
console.log(p3.printName());//Oops

取值函數(getter)和存值函數(setter)

prop屬性有對應的存值函數和取值函數

class MyClass {
   constructor(){
        //...
    }
    get prop(){
        return 'getter';
    }
    set prop(value){
        console.log("setter:" + value);
    }
}
const inst = new MyClass();
inst.prop = 123;//setter: 123
console.log(inst.prop)//getter

存值函數和取值函數是設置在屬性的Descriptor對象上的

class CustomHTMLElement {
   constructor(element) {
        this.element = element;
    }

    get html() {
        return this.element.innerHTML;
    }

    set html(value) {
        this.element.innerHTML = value;
    }
}

const descriptor = Object.getOwnPropertyDescriptor(
    CustomHTMLElement.prototype, "html"
);

console.log("get" in descriptor)  // true
console.log("set" in descriptor)  // true

calss 表達式

const MyCl = class Me {
    getClassName() {
        return Me.name;
    }
}
const inMe = new MyCl();
console.log(inMe.getClassName());//Me  只在class內部有定義

person立即執行實例

const person = new class{
    constructor(name){
        this.name = name;
    }
    sayName(){
        console.log(this.name);
    }
}('張三');
person.sayName();//張三

class name 屬性

class Mine {
//...
}
console.log(Mine.name);//Mine

class this的指向問題

this.printName = this.printName.bind(this)綁定解決

class Logger{
   constructor(){
        this.printName = this.printName.bind(this);
    }
    printName(name = 'there'){
        this.print(`Hello ${name}`);
    }
    print(text){
        console.log(text);
    }
}
const logger = new Logger();
const {printName} = logger;
printName();//Hello there

靜態方法static

如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是通過類來調用

class Foo{
    static classMethod() {
        return 'hello';
    }
}
console.log(Foo.classMethod());//Hello

const foo = new Foo();
// console.log(foo.classMethod())//foo.classMethod is not a function
class Fun {
   static bar(){
       this.baz();
   }
   static baz(){
       console.log('hello');
   }
   baz(){
       console.log('world');
   }
}
Fun.bar();//hello

父類靜態方法可以被子類調用

class Func{
   static classMethod() {
        return 'hello';
    }
}
class Baa extends Func{
    static classMethod(){
        console.log(super.classMethod + ",too") ;
    }
}
Baa.classMethod();//hello,too

實例屬性的新寫法

class IncreasingCounter{
    // constructor(){
    //     this._count = 0;
    // }
    _count = 0;
    get value(){
        console.log('getting the current value');  
        return this._count;           
    }
    increment(){
        this._count++;
    }
}

new.target屬性

確保函數只能通過new命令調用

function PersonMan(name){
    if(new.target !== undefined){
        this.name = name;
    }else{
        throw new Error('必須使用new命令生成實例')
    }
}
function PersonWoman(name){
    if(new.target === PersonWoman){
        this.name = name;
    }else{
        throw new Error('必須使用new命令生成實例')
    }
}
const personman = new PersonMan('張三');
const personwoman = new PersonWoman('張三');
// const personwoman2 =  PersonWoman.call(PersonWoman,'張三');//報錯

內部調用new.target會返回當前的class

class Rectangle{
    constructor(length,width){
        console.log(new.target);
        console.log(new.target===Rectangle);
        this.length = length;
        this.width = width;
    }
}
const rectangle = new Rectangle(3,4);

子類繼承父類時,new.target會返回子類

class Rec{
   constructor(length,width){
        console.log(new.target);
        console.log(new.target===Rectangle);
        console.log(new.target===Square);
        this.length = length;
        this.width = width;
        //...
    }
}
class Square extends Rec{
    constructor(length,width){
        super(length,width);
    }
}
const squareA = new Square(3,6);//false/true

參考文章
探索ES6
ES6阮一峰

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

林口县| 罗平县| 巨野县| 镇坪县| 辰溪县| 大悟县| 余江县| 锦屏县| 苍溪县| 酒泉市| 乡城县| 田阳县| 闸北区| 建德市| 利辛县| 信丰县| 顺平县| 南充市| 淳安县| 平顺县| 宁蒗| 浮山县| 石渠县| 克什克腾旗| 舒兰市| 萍乡市| 宜兴市| 鸡泽县| 浮山县| 呈贡县| 九江市| 永清县| 惠州市| 安达市| 花莲县| 铅山县| 牟定县| 西乌珠穆沁旗| 香河县| 徐汇区| 嘉鱼县|