ES6 -- 類別(Class)

JavaScript是prototype-based的語言, ES6只是提供語法糖, 也就是說: 只是寫的像那些傳統語言物件導向的寫法, 但程式運作方式還是prototype-based語言。

當我們想要new一個物件時:

ES5時會這麼寫:

e.g.

var Shape1 = function(id, x, y) {

    this.id = id;
    this.move(x, y);

};

Shape1.prototype.move = function(x, y) {

    this.x = x;
    this.y = y;

};

var a = new Shape1("a", 0, 0);

console.log(a);                                                              // Shape1 {id: "a", x: 0, y: 0}



在ES6會這麼寫:

e.g.

class Shape2 {

    constructor(id, x, y) {

        this.id = id
        this.move(x, y)

    }
    move(x, y) {

        this.x = x
        this.y = y

    }

}

var a = new Shape2("a", 0, 0);

console.log(a);                                                              // Shape2 {id: "a", x: 0, y: 0}



另外, 當我們想寫類別的繼承時:

在ES5我們會這麼寫:

e.g.

Object.prototype.inherits = function(superCtor) {

var F = function() {};
F.prototype = superCtor.prototype;
this.prototype = new F();
this.uber = superCtor.prototype;
this.prototype.constructor = this;

};

var Shape1 = function(id, x, y) {

this.id = id;
this.move(x, y);

};

Shape1.prototype.move = function(x, y) {

this.x = x;
this.y = y;

};

var Rectangle1 = function(id, x, y, width, height) {

Shape1.call(this, id, x, y);
this.width = width;
this.height = height;

};

Rectangle1.inherits(Shape1);

var Circle1 = function(id, x, y, radius) {

Shape1.call(this, id, x, y);
this.radius = radius;

};

Circle1.inherits(Shape1);

var a = new Rectangle1("a", 0, 0, 100, 100);

console.log(a);                                                                              // Rectangle1 {id: "a", x: 0, y: 0, width: 100, height: 100}

var b = new Circle1("b", 0, 0, 100);

console.log(b);                                                                              // Circle1 {id: "b", x: 0, y: 0, radius: 100}



在ES6會這麼寫:

e.g.

class Shape2 {

constructor(id, x, y) {

this.id = id;
this.move(x, y);

}
move(x, y) {

this.x = x;
this.y = y;

}

}

class Rectangle2 extends Shape2 {

constructor(id, x, y, width, height) {

super(id, x, y);
this.width = width;
this.height = height;

}

}

class Circle2 extends Shape2 {

constructor(id, x, y, radius) {

super(id, x, y);
this.radius = radius;

}

}

var a = new Rectangle2("a", 0, 0, 100, 100);

console.log(a);                                                                                // Rectangle2 {id: "a", x: 0, y: 0, width: 100, height: 100}

var b = new Circle2("b", 0, 0, 100);

console.log(b);                                                                                // Circle2 {id: "b", x: 0, y: 0, radius: 100}



再者, 如果我們希望寫"靜態方法"(指不透過new就能使用的方法)時:

在ES5時這麼寫:

e.g.

Object.prototype.inherits = function(superCtor) {

var F = function() {};
F.prototype = superCtor.prototype;
this.prototype = new F();
this.uber = superCtor.prototype;
this.prototype.constructor = this;

};

var Shape1 = function(id, x, y) {

this.id = id;
this.move(x, y);

};

Shape1.prototype.move = function(x, y) {

this.x = x;
this.y = y;

};

var Rectangle1 = function(id, x, y, width, height) {

Shape1.call(this, id, x, y);
this.width = width;
this.height = height;

};

Rectangle1.inherits(Shape1);

Rectangle1.defaultRectangle = function() {

return new Rectangle1("default", 0, 0, 100, 100);

};

var Circle1 = function(id, x, y, radius) {

Shape1.call(this, id, x, y);
this.radius = radius;

};

Circle1.inherits(Shape1);

Circle1.defaultCircle = function() {

return new Circle1("default", 0, 0, 100);

};

var defRectangle = Rectangle1.defaultRectangle();

console.log(defRectangle);                                                        // Rectangle1 {id: "default", x: 0, y: 0, width: 100, height: 100}

var defCircle = Circle1.defaultCircle();

console.log(defCircle);                                                                 // Circle1 {id: "default", x: 0, y: 0, radius: 100}



在ES6會這麼寫:

e.g.

class Shape2 {

constructor(id, x, y) {

this.id = id;
this.move(x, y);

}
move(x, y) {

this.x = x;
this.y = y;

}

}

class Rectangle2 extends Shape2 {

constructor(id, x, y, width, height) {

super(id, x, y);
this.width = width;
this.height = height;

}
static defRectangle() {

return new Rectangle2("default", 0, 0, 100, 100);

}

}

class Circle2 extends Shape2 {

constructor(id, x, y, radius) {

super(id, x, y);
this.radius = radius;

}
static defCircle() {

return new Circle2("default", 0, 0, 100);

}

}

var defRectangle = Rectangle2.defRectangle();

console.log(defRectangle);                                                         // Rectangle2 {id: "default", x: 0, y: 0, width: 100, height: 100}

var defCircle = Circle2.defCircle();

console.log(defCircle);                                                                  // Circle2 {id: "default", x: 0, y: 0, radius: 100}          



最後, 當我們想用GetterSetter:

之前我們提過Vue.js就是用GetterSetter去動態監控DOM的變化,在這裡再介紹一下GetterSetter:
    Getter – 用來取得特定屬性的值的方法
    Setter – 用來設定特定屬性的值的方法

我們可以在任何能新增新屬性的”predefined object”(Date object)”user-defined object”(我們自創的物件)中去寫GetterSetter

何時會用到GetterSetter?
--> 情況1: 一開始建立一個物件時就使用(object initializers)。通常指新增在原型中。
     情況2: 在建立物件後的任何時間點想新增GetterSetter方法也可以。通常指一開始未在原型中新增GetterSetter, 之後卻有想新增的需求。

一般傾向使用在情況1, 因為情況2會使整體codes變得較難以閱讀和理解, 也就是難維護。


ES5中寫GetterSetter:

e.g.

var Rectangle1 = function(width, height) {

    this._width = width;
    this._height = height;

};

Rectangle1.prototype = {

    set width(width) {

        this._width = width;

    },
    get width() {

        return this._width;

    },
    set height(height) {

        this._height = height;

    },
    get height() {

        return this._height;

    },
    get area() {

        return this._width * this._height;

    }

};

var r = new Rectangle1(50, 20);

console.log(r.area === 1000);                      // true



ES6會這麼寫, 其實和ES5寫法差不多:

e.g.

class Rectangle2 {

    constructor(width, height) {

        this._width = width
        this._height = height

    }
    set width(width) {

        this._width = width

    }
    get width() {

        return this._width

    }
    set height(height) {

        this._height = height

    }
    get height() {

        return this._height

    }
    get area() {

        return this._width * this._height

    }

}

var r = new Rectangle2(50, 20)


console.log(r.area === 1000);                     // true



留言

熱門文章