前言:以前看过公司大神的代码,发现有不少构造函数,相似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