ES6Class
1. 用法
class Animal{
type='哺乳類';//聲明到實例上
constructor(){}//相當于function Animal(){}
say(){}//放到原型上
get a(){}//放到原型上 相當于Object.defineProperty(Animal.prototype,a,{get(){ }})
static flag='動物'//靜態屬性 ES7 ES6只有靜態方法
static get flag(){return '動物'}//ES6靜態屬性 相當于Object.defineProperty(Animal,a,{get(){ }})
}
2. ES5類的繼承
//Object.setPrototypeOf( Child.prototype , Father.prototype );
Child.prototype = Object.create( Animal.prototype ,{ constructor : { value : Child } } );
//create原理
let create = (parentProto, constructor) => {
function fn() { };
fn.prototype = parentProto;
let newFn = new fn;
newFn.constructor = constructor;
return newFn;
}
3. ES6類的繼承
call + Object.create() + Object.setPrototypeOf()
class Animal {
constructor(name) {
this.name = name;
}
static type() {
console.log('動物');
}
say() {
console.log('say');
}
}
class Tiger extends Animal {
constructor(name) {
super(name)//這里super===Animal
}
static type() {
super.type()//這里super===Animal
}
say() {
super.say()//這里super===Animal.prototype
}
}
4. new的原理
function mockNew(constructor, ...args) {
let obj = Object.create(null);
Object.setPrototypeOf(obj, constructor.prototype)
let value = constructor.call(obj, args);
return value != null && typeof value === 'object' ? value : obj;
}
5. 裝飾器
在執行類之前可以進行包裝,裝飾器必須是一個函數,只能修飾類的屬性和類的方法。參數分別是類的原型、裝飾的key、和key對應的屬性描述器。
//裝飾器 必須是一個函數,只能修飾類 (類中的屬性 還有類中的方法) 參數分別是 類的原型 裝飾的key 和key對應的屬性描述器
@type1('哺乳1')
@type2('哺乳2')
class Circle{
@readonly PI = 3.14;
@before
say(){
console.log('say')
}
}
// 對類進行擴展
function type1(type1){
console.log('t1')
return function(Constructor){
console.log('innerT1')
Constructor.type1 = type1
}
}
// 對類進行擴展
function type2(type2){
console.log('t2')
return function(Constructor){
console.log('innerT2')
Constructor.type2 = type2
}
}
//修飾屬性
function readonly(CirclePrototype,key,descriptor){
descriptor.writable = false;
descriptor.enumerable = false;
}
//修飾方法
function before(CirclePrototype,key,descriptor){
let oldSay = descriptor.value; // 函數劫持
descriptor.value = function(){ // 將函數原有的邏輯 進行包裝
console.log('before')
oldSay()
}
}
let c = new Circle();
c.say();
// 實驗型語法 目前node不支持
// mixin 混合
let obj = {
name:'zf',
age:'10',
}
@mixin(obj)
class School{
}
function mixin(obj){
return function(Constructor){
Object.assign(Constructor.prototype,obj)
}
}
let school = new School;
console.log(school.name,school.age);