在 ES6 中创建多个构造函数
Creating multiple constructor in ES6
在 ES5 中,可以为 class 创建多个构造函数,同时使用原型保留两者的公共部分,如下所示
function Book() {
//just creates an empty book.
}
function Book(title, length, author) {
this.title = title;
this.Length = length;
this.author = author;
}
Book.prototype = {
ISBN: "",
Length: -1,
genre: "",
covering: "",
author: "",
currentPage: 0,
title: "",
flipTo: function FlipToAPage(pNum) {
this.currentPage = pNum;
},
turnPageForward: function turnForward() {
this.flipTo(this.currentPage++);
},
turnPageBackward: function turnBackward() {
this.flipTo(this.currentPage--);
}
};
var books = new Array(new Book(), new Book("First Edition", 350, "Random"));
我想使用 ES6 class 和构造函数语法达到相同的结果
class Book{
constructore (){}
}
Function/constructor ECMAScript 不支持重载。如果你仍然想破解它,你可以使用参数对象来做到这一点。
constructor(title, length, author) {
if(!arguments.length) {
// empty book
}
else {
this.title = title;
this.Length = length;
this.author = author;
}
}
其实,确实可以为一个原型创建多个构造函数。你只需要看到原型 is not special 的 constructor
属性。因此,可以创建多个构造函数如下:
const type = (prototype, constructor) =>
(constructor.prototype = prototype, constructor);
const book = {
flipTo(page) {
this.page = page;
},
turnPageForward() {
this.page++;
},
turnPageBackward() {
this.page--;
}
};
const EmptyBook = type(book, function EmptyBook() {
this.constructor = EmptyBook;
this.ISBN = "";
this.title = "";
this.author = "";
this.genre = "";
this.covering = "";
this.length = -1;
this.page = 0;
});
const Book = type(book, function Book(title, author, length) {
this.constructor = Book;
this.ISBN = "";
this.title = title;
this.author = author;
this.genre = "";
this.covering = "";
this.length = length;
this.page = 0;
});
只是给构造器起不同的名字。希望对您有所帮助。
您也可以通过使用带有扩展的 ES6 类 来绕过这个限制。
class Base{
Foo;
Bar;
}
class TypeA extends Base {
constructor(value) {
this.Foo = value;
}
}
class TypeB extends Base {
constructor(value) {
this.Bar = value;
}
}
我相信有两个答案。一种使用'pure' Javascript 和IIFE 函数来隐藏它的辅助构造函数。而另一个使用NodeJS模块也隐藏了它的辅助构造函数。
我将只展示带有 NodeJS 模块的示例。
Class Vector2d.js:
/*
Implement a class of type Vetor2d with three types of constructors.
*/
// If a constructor function is successfully executed,
// must have its value changed to 'true'.let global_wasExecuted = false;
global_wasExecuted = false;
//Tests whether number_value is a numeric type
function isNumber(number_value) {
let hasError = !(typeof number_value === 'number') || !isFinite(number_value);
if (hasError === false){
hasError = isNaN(number_value);
}
return !hasError;
}
// Object with 'x' and 'y' properties associated with its values.
function vector(x,y){
return {'x': x, 'y': y};
}
//constructor in case x and y are 'undefined'
function new_vector_zero(x, y){
if (x === undefined && y === undefined){
global_wasExecuted = true;
return new vector(0,0);
}
}
//constructor in case x and y are numbers
function new_vector_numbers(x, y){
let x_isNumber = isNumber(x);
let y_isNumber = isNumber(y);
if (x_isNumber && y_isNumber){
global_wasExecuted = true;
return new vector(x,y);
}
}
//constructor in case x is an object and y is any
//thing (he is ignored!)
function new_vector_object(x, y){
let x_ehObject = typeof x === 'object';
//ignore y type
if (x_ehObject){
//assigns the object only for clarity of code
let x_object = x;
//tests whether x_object has the properties 'x' and 'y'
if ('x' in x_object && 'y' in x_object){
global_wasExecuted = true;
/*
we only know that x_object has the properties 'x' and 'y',
now we will test if the property values are valid,
calling the class constructor again.
*/
return new Vector2d(x_object.x, x_object.y);
}
}
}
//Function that returns an array of constructor functions
function constructors(){
let c = [];
c.push(new_vector_zero);
c.push(new_vector_numbers);
c.push(new_vector_object);
/*
Your imagination is the limit!
Create as many construction functions as you want.
*/
return c;
}
class Vector2d {
constructor(x, y){
//returns an array of constructor functions
let my_constructors = constructors();
global_wasExecuted = false;
//variable for the return of the 'vector' function
let new_vector;
//traverses the array executing its corresponding constructor function
for (let index = 0; index < my_constructors.length; index++) {
//execute a function added by the 'constructors' function
new_vector = my_constructors[index](x,y);
if (global_wasExecuted) {
this.x = new_vector.x;
this.y = new_vector.y;
break;
};
};
}
toString(){
return `(x: ${this.x}, y: ${this.y})`;
}
}
//Only the 'Vector2d' class will be visible externally
module.exports = Vector2d;
useVector2d.js文件使用了Vector2d.js模块:
const Vector = require('./Vector2d');
let v1 = new Vector({x: 2, y: 3});
console.log(`v1 = ${v1.toString()}`);
let v2 = new Vector(1, 5.2);
console.log(`v2 = ${v2.toString()}`);
let v3 = new Vector();
console.log(`v3 = ${v3.toString()}`);
终端输出:
v1 = (x: 2, y: 3)
v2 = (x: 1, y: 5.2)
v3 = (x: 0, y: 0)
这样我们就避免了脏代码(许多 if 和 switch 遍布整个代码),难以维护和测试。每个建筑功能都知道要测试哪些条件。增加和/或减少您的建筑功能现在很简单。
在 ES5 中,可以为 class 创建多个构造函数,同时使用原型保留两者的公共部分,如下所示
function Book() {
//just creates an empty book.
}
function Book(title, length, author) {
this.title = title;
this.Length = length;
this.author = author;
}
Book.prototype = {
ISBN: "",
Length: -1,
genre: "",
covering: "",
author: "",
currentPage: 0,
title: "",
flipTo: function FlipToAPage(pNum) {
this.currentPage = pNum;
},
turnPageForward: function turnForward() {
this.flipTo(this.currentPage++);
},
turnPageBackward: function turnBackward() {
this.flipTo(this.currentPage--);
}
};
var books = new Array(new Book(), new Book("First Edition", 350, "Random"));
我想使用 ES6 class 和构造函数语法达到相同的结果
class Book{
constructore (){}
}
Function/constructor ECMAScript 不支持重载。如果你仍然想破解它,你可以使用参数对象来做到这一点。
constructor(title, length, author) {
if(!arguments.length) {
// empty book
}
else {
this.title = title;
this.Length = length;
this.author = author;
}
}
其实,确实可以为一个原型创建多个构造函数。你只需要看到原型 is not special 的 constructor
属性。因此,可以创建多个构造函数如下:
const type = (prototype, constructor) =>
(constructor.prototype = prototype, constructor);
const book = {
flipTo(page) {
this.page = page;
},
turnPageForward() {
this.page++;
},
turnPageBackward() {
this.page--;
}
};
const EmptyBook = type(book, function EmptyBook() {
this.constructor = EmptyBook;
this.ISBN = "";
this.title = "";
this.author = "";
this.genre = "";
this.covering = "";
this.length = -1;
this.page = 0;
});
const Book = type(book, function Book(title, author, length) {
this.constructor = Book;
this.ISBN = "";
this.title = title;
this.author = author;
this.genre = "";
this.covering = "";
this.length = length;
this.page = 0;
});
只是给构造器起不同的名字。希望对您有所帮助。
您也可以通过使用带有扩展的 ES6 类 来绕过这个限制。
class Base{
Foo;
Bar;
}
class TypeA extends Base {
constructor(value) {
this.Foo = value;
}
}
class TypeB extends Base {
constructor(value) {
this.Bar = value;
}
}
我相信有两个答案。一种使用'pure' Javascript 和IIFE 函数来隐藏它的辅助构造函数。而另一个使用NodeJS模块也隐藏了它的辅助构造函数。
我将只展示带有 NodeJS 模块的示例。
Class Vector2d.js:
/*
Implement a class of type Vetor2d with three types of constructors.
*/
// If a constructor function is successfully executed,
// must have its value changed to 'true'.let global_wasExecuted = false;
global_wasExecuted = false;
//Tests whether number_value is a numeric type
function isNumber(number_value) {
let hasError = !(typeof number_value === 'number') || !isFinite(number_value);
if (hasError === false){
hasError = isNaN(number_value);
}
return !hasError;
}
// Object with 'x' and 'y' properties associated with its values.
function vector(x,y){
return {'x': x, 'y': y};
}
//constructor in case x and y are 'undefined'
function new_vector_zero(x, y){
if (x === undefined && y === undefined){
global_wasExecuted = true;
return new vector(0,0);
}
}
//constructor in case x and y are numbers
function new_vector_numbers(x, y){
let x_isNumber = isNumber(x);
let y_isNumber = isNumber(y);
if (x_isNumber && y_isNumber){
global_wasExecuted = true;
return new vector(x,y);
}
}
//constructor in case x is an object and y is any
//thing (he is ignored!)
function new_vector_object(x, y){
let x_ehObject = typeof x === 'object';
//ignore y type
if (x_ehObject){
//assigns the object only for clarity of code
let x_object = x;
//tests whether x_object has the properties 'x' and 'y'
if ('x' in x_object && 'y' in x_object){
global_wasExecuted = true;
/*
we only know that x_object has the properties 'x' and 'y',
now we will test if the property values are valid,
calling the class constructor again.
*/
return new Vector2d(x_object.x, x_object.y);
}
}
}
//Function that returns an array of constructor functions
function constructors(){
let c = [];
c.push(new_vector_zero);
c.push(new_vector_numbers);
c.push(new_vector_object);
/*
Your imagination is the limit!
Create as many construction functions as you want.
*/
return c;
}
class Vector2d {
constructor(x, y){
//returns an array of constructor functions
let my_constructors = constructors();
global_wasExecuted = false;
//variable for the return of the 'vector' function
let new_vector;
//traverses the array executing its corresponding constructor function
for (let index = 0; index < my_constructors.length; index++) {
//execute a function added by the 'constructors' function
new_vector = my_constructors[index](x,y);
if (global_wasExecuted) {
this.x = new_vector.x;
this.y = new_vector.y;
break;
};
};
}
toString(){
return `(x: ${this.x}, y: ${this.y})`;
}
}
//Only the 'Vector2d' class will be visible externally
module.exports = Vector2d;
useVector2d.js文件使用了Vector2d.js模块:
const Vector = require('./Vector2d');
let v1 = new Vector({x: 2, y: 3});
console.log(`v1 = ${v1.toString()}`);
let v2 = new Vector(1, 5.2);
console.log(`v2 = ${v2.toString()}`);
let v3 = new Vector();
console.log(`v3 = ${v3.toString()}`);
终端输出:
v1 = (x: 2, y: 3)
v2 = (x: 1, y: 5.2)
v3 = (x: 0, y: 0)
这样我们就避免了脏代码(许多 if 和 switch 遍布整个代码),难以维护和测试。每个建筑功能都知道要测试哪些条件。增加和/或减少您的建筑功能现在很简单。