ES6中類的基本語法

1.瞭解類的使用

// 1.定義類
class Person{
	// 構造函數 初始化實例
	constructor(name,age){
		this.name=name;
		this.age=age;
	}
	// 重寫toString()方法
	toString(){
		return `姓名:${this.name}—— 年齡:${this.age}`
	}
}

// 創建一個Person實例並傳遞名字和年齡
let p=new Person('法外狂徒張三',30);
console.log(p.toString());  // 姓名:法外狂徒張三—— 年齡:30

// 2. ES的類完全可以看成是構造函數的新寫法 或者說語法糖
console.log(typeof Person); // function
console.log(Person===Person.prototype.constructor); // true

// 3. 可以使用Object.assgin()方法爲類添加新的實例方法
// 注意:是要添加到類的原型對象prototype上 不是直接添加到類上
Object.assign(Person.prototype,{
    run(){
        console.log("跑步");
    }
})
p.run();

// 4.類中一開始就定義的方法都是不可枚舉的 使用Object.keys()是無法枚舉類的prototype屬性
// 但是,後來使用Object.assgin()添加到原型上的方法是可以獲取的
console.log(Object.keys(Person.prototype)); // ['run']
console.log(Object.getOwnPropertyNames(Person.prototype)); // [ 'constructor', 'toString', 'eat', 'run' ]
console.log(Reflect.ownKeys(Person.prototype)); // [ 'constructor', 'toString', 'eat', 'run' ]

2.constructor構造函數

2.1constructor方法是類的默認構造方法,通過new命令生成對象實例,自動調用該方法。
一個類必須有有constructor方法 如果沒有主動定義 那麼系統會自動添加一個空的constructor方法
class Person{

}
// 等價於
class Person{
    constructor(){
        
    }
}
2.2 默認情況下 constructor返回實例對象this,但是也可以通過return返回指定的對象
class Person{
    constructor(){
        return{
            name:'zs'
        }
    }
}
// 可以看出來 實例出來的對象並不是this 而是我們指定的
console.log(new Person() instanceof Person); //false 
console.log(new Person());    // { name: 'zs' }
2.3 類必須使用new調用,否則報錯
let p=Person();// 報錯:Class constructor Person cannot be invoked without 'new'

3.類的實例

let f='favorite';
let s='sport';
class Person{
    constructor(name){
        this.name=name
    }
    getName(){
        return this.name;
    }
    setName(name){
        this.name=name;
        console.log("設置了新的名字");
    }
    // 屬性名可以使用表達式 但是需要用[]包起來
    [f+s](){
       console.log("跑步");
    }
}

let p1=new Person('zs');
let p2=new Person('ls');
// 不同是實例對象共享同一個原型對象
console.log(p1.__proto__===p2.__proto__);

// 使用set和get關鍵字設置某個屬性的存取函數,設置和讀取行爲會被修改
p1.setName='ww';         // 設置name的設置行爲    打印:設置了新的名字
console.log(p1.getName); // 改變name的讀取行爲    打印:新名字:ww

4.靜態方法

// 類相當於實例的原型 所有定義在類中的方法都會被實例繼承 
// 但是如果有一個方法使用static修飾 則表示這個方式是靜態方法
// 靜態方法不會被實例繼承 而是直接通過類名.的方法調用
class Person{
    static classMethod(){
        // 靜態方法中的this指向的類 而不是實例
        console.log(this===Person);   //true 即這裏的this是Person類本身
        console.log("靜態方法 實例無法調用");
    }
    classMethod(){
        console.log(this instanceof Person); // true 即這裏的this是類的實例
        console.log("實例方法 實例可以調用");
    }
}
let p=new Person();
Person.classMethod();    
p.classMethod();

5.靜態屬性

// 靜態屬性和靜態方法類似 只能通過類名.的方法訪問
class Person{
	// 這種方式還在提案 暫時不能這樣用
	// static age;
}
Person.sport="跑步";
console.log(Person.sport);  // 跑步 

let p=new Person();    // 實例對象無法訪問靜態屬性和靜態方法
console.log(p.sport);  // undefined

6. 私有屬性和私有方法

// 現在其實並沒有真正意義上的私有方法和私有屬性 只是通過命名進行提示
let foo=Symbol('foo');
class Person{
    constructor(){
        this._privateAttr='私有屬性';
        this.publicAttr='公有屬性';
    }
    publicMethod(){
        console.log("公有方法")
    }
    _privateMethod(){
        console.log('私有方法')
    }
    // 也可以使用Symbol來設置私有方法
    [foo](){
        console.log("使用Symbol設置私有方法")
    }
}
let p=new Person();  
p.publicMethod();      // 公有方法
p._privateMethod();    // 私有方法
p[foo]();              // 使用Symbol設置私有方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章