前言:以前看過公司大神的代碼,發現有不少構造函數,相似Java和C#的 new 方法來實例化一個對象,感受非常受教,恰好最近在用es6,發現了用class來實現構造函數,因而總結了一下,也是回顧和提升的過程,因爲本人也是前端小白,文章可能有不少錯誤,歡迎各位大神批評指正~~前端
// 常規方法一 function Persion(name, age) { this.name = name; // this.key 賦值,則直接掛載到Persion實例 this.age = age; this.getInfo = function() { return { name: this.name, age: this.age } } } // 調用 var persion = new Persion('張三', 15); // 此時的persion實例擁有name、age、getInfo()三個屬性及方法 // 常規方法二 function Persion(name, age) { var name = name; var age = age; var getInfo = function() { return { name: name, age: age, } } return { // 經過return將元素暴露給實例對象 name: name, age: age, getInfo: getInfo, } } // 調用 var persion = new Persion('張三', 15); // 此時的persion實例擁有name、age、getInfo()三個屬性及方法
class Persion { constructor(name, age) { // 一個類必須有constructor方法, 若是沒有顯式定義, 一個空的constructor方法會被默認添加。 this.name = name; this.age = age; } getInfo() { return { name: this.name, age: this.age, } } } // 調用 const persion = new Persion('張三', 17); // 此時的persion實例擁有name、age、getInfo()三個屬性及方法
注:ES6 class 聲明構造函數會將全部內部元素暴露出來,但有的時候咱們但願這些方法只在內部聲明時使用,並不暴露給實例對象,在ES5中咱們能夠很方便的作到,以下栗子:es6
// ES5 實現私有方法 // 方案一 function Persion(name, age) { this.name = name; this.age = age; var print = function(){ return name + '今年' + age + '歲了!'; } this.setName = function(newName){ this.name = newName; } this.setAge = function(newAge){ this.age = newAge; } this.getInfo = function(){ { name: name, age: age, } } this.printInfo = function(){ console.log(print()); } } // 實例化 var persion = newPersion('張三', 15); // 方案二 function Persion(name, age) { var name = name, age = age; // print做爲私有方法,只在內部用於生成輸出字符串,並不須要暴露到外部 var print = function(){ return name + '今年' + age + '歲了!'; } var setName = function(newName){ name = newName; } var setAge = function(newAge){ age = newAge; } var getInfo = function(){ { name: name, age: age, } } var printInfo = function(){ console.log(print()); } return { name: name, age: age, setName: setName, setAge: setAge, getInfo: getInfo, printInfo: printInfo, } } // 實例化 var persion = newPersion('張三', 15); // 此時實例化的persion 將不會暴露出print方法,我我的更傾向於方案二的方法,能夠清楚的看出哪些屬性和方法須要暴露出來,也容易修改須要暴露的接口。
那麼在ES6中咱們要怎麼實現私有的方法和屬性呢?其實方法不少,但都很不友好,我只總結了三種,若是有什麼好的方法歡迎你們給我留言,不勝感激:)segmentfault
// 私有方法 變通方案 // 方案一 (其實並不算一個方法。。。) class Persion { constructor(name, age) { this.name = name; this.age = age; } _print() { // 一般以「_」開頭命名的方法爲內部私有方法 return name + '今年' + age + '歲了!'; } setName(newName) { this.name = newName; } setName(newAge) { this.age= newAge; } printInfo() { console.log(_print()); } getInfo() { return { name: this.name, name: this.age, } } } // 實例化 const persion = new Persion('張三', 15); // 此時persion實例仍然能獲取到_print方法,只能用來區分私用和公有方法而已; // 方案二 // 注意若使用ES6箭頭函數則this指向的是該方法自己,而非調用它的對象, function _print() { // 外部聲明_print 方法,在內部調用,此時_print 成爲Persion類的私有方法 return this.name + '今年' + this.age + '歲了!'; } class Persion { constructor(name, age) { this.name = name; this.age = age; } setName(newName) { this.name = newName; } setName(newAge) { this.age= newAge; } printInfo() { console.log(_print()); } getInfo() { return { name: this.name, name: this.age, } } } // 實例化 const persion = new Persion('張三', 15); // 此時persion實例獲取不到_print方法; // 方案三 const print = Symbol('print'); // 聲明一個Symbol值,用來作爲私有方法的名字 class Persion { constructor(name, age) { this.name = name; this.age = age; } setName(newName) { this.name = newName; } setName(newAge) { this.age= newAge; } [bar]() { // 將私有方法的名字命名爲一個Symbol值。 return this.name + '今年' + this.age + '歲了!'; } printInfo() { console.log([bar]()); // 調用私有方法 } getInfo() { return { name: this.name, name: this.age, } } } // 實例化 const persion = new Persion('張三', 15); // 此時persion實例獲取不到[bar]方法;
# 追更
感謝 @黒之染 的評論, 構造函數還能夠經過prototype來添加對象函數
栗子: ``` function Persion(name, age){ this.name = name, this.age = age, } Persion.prototype.getInfo = function(){ return { name: this.name, age: this.name, } } // 實例化 var persion = new Persion('張三'); // 此時實例化後的對象persion擁有getInfo()方法 persion.getInfo() // 輸出{name: '張三'} ```
關於js構造函數的繼承能夠看一下個人下一篇文章js構造函數(繼承方法及利弊)this