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}
當我們想要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}
最後, 當我們想用Getter和Setter時:
之前我們提過Vue.js就是用Getter和Setter去動態監控DOM的變化,在這裡再介紹一下Getter和Setter:
Getter – 用來取得特定屬性的值的方法
Setter – 用來設定特定屬性的值的方法
我們可以在任何能新增新屬性的”predefined object”(如Date object)和”user-defined object”(我們自創的物件)中去寫Getter和Setter。
何時會用到Getter和Setter呢?
--> 情況1: 一開始建立一個物件時就使用(object initializers)。通常指新增在原型中。
情況2: 在建立物件後的任何時間點想新增Getter和Setter方法也可以。通常指一開始未在原型中新增Getter和Setter, 之後卻有想新增的需求。
一般傾向使用在情況1, 因為情況2會使整體codes變得較難以閱讀和理解, 也就是難維護。
在ES5中寫Getter和Setter:
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
留言
張貼留言