我们用组合构造函数和原型模式来创建构造器,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。那么。如何让构造函数模式中的方法不被实例所创建呢?比如下面这个例子:
function Person(name, family) {
this.name = name;
this.family = family;
var records = [{type: "in", amount: 0}];
this.addTransaction = function(trans) {
if(trans.hasOwnProperty("type") && trans.hasOwnProperty("amount")) {
records.push(trans);
}
}
this.balance = function() {
var total = 0;
records.forEach(function(record) {
if(record.type === "in") {
total += record.amount;
}
else {
total -= record.amount;
}
});
return total;
};
};
Person.prototype.getFull = function() {
return this.name + " " + this.family;
};
Person.prototype.getProfile = function() {
return this.getFull() + ", total balance: " + this.balance();
};
var me = new Person('sun','yang');
me.balance//0
me.getProfile()//"sun yang, total balance: 0"
在这个Person构造函数内部有一个records 的私有变量,这个变量我们是不希望通过函数内部以外的方法去操作这个变量, 但是又想通过构造函数new出来的对象能获取构造函数内部的私有变量,所以在构造函数内定义了两个方法addTransaction和balance(有点像闭包的概念),这两个方法是处理变量的,并把处理的结果赋给Person.prototype上共享给实例。那么问题来了
在构造函数内部的addTransaction和balance两个方法只是为了处理变量,并不想被实例创建一个副本,这只是一个简单的例子,如果在一个复杂的构造器,里面有很多这样的方法,那岂不是会造成巨大的内存浪费吗?
另外我在ES6中看到有Class的静态方法,似乎可以解决这样的问题,将上面的例子改写成es6的形式:
class Person{
constructor(name, family) {
this.name = name;
this.family = family;
}
static addTransaction = function(trans) {
if(trans.hasOwnProperty("type") && trans.hasOwnProperty("amount")) {
records.push(trans);
}
}
static balance = function() {
let records = [{type: "in", amount: 0}];
let total = 0;
records.forEach(function(record) {
if(record.type === "in") {
total += record.amount;
}
else {
total -= record.amount;
}
});
return total;
}
getFull = function() {
return this.name + " " + this.family;
}
getProfile = function() {
return this.getFull() + ", total balance: " + Person.balance();
}
}
let me = new Person('sun','yang');
console.log(me)
如上,我这样写没有报错,另外这两个只是用作处理构造函数内部的方balanceaddTransaction也没被实例所创建。,那么我想知道,虽然我这样写是没有报错,但是自己能力水平很差,可能是自己理解错了,也可能这就不是个问题。如果我没理解错的话,ES6可以这么写,那ES5这个问题是怎么解决的呢?