我有三种创建函数并返回它的方法。 (也许还有更多?)但我不知道它们之间的区别以及何时使用哪个。 有人可以解释一下吗。
var test1 = function() {
var funk1 = function() {
console.log(1);
}
var funk2 = function(msg) {
console.log(msg);
}
return {
funk1: funk1,
funk2: funk2
}
};
var test2 = function() {
this.funk1 = function() {
console.log(1);
}
this.funk2 = function(msg) {
console.log(msg);
}
};
var someThing = test1();
someThing.funk1();
someThing.funk2(2);
var someThing = new test1();
someThing.funk1();
someThing.funk2(2);
var thingElse = new test2();
thingElse.funk1();
thingElse.funk2(2);
最佳答案
这是模块/库/插件模式
var test1 = function() {
var funk1 = function() {
console.log(1);
}
return {
funk1: funk1
}
};
这是 OOP(面向对象编程)模式
var test2 = function() {
this.funk1 = function() {
console.log(1);
}
};
区别
var t = test1() //function call, t is result of test1 function execution
var t = new test1() //instance initialization, t is instance of test1 class
考虑这个简单的模型
我们有一个制造汽车的制造商,制造商有一些方法,汽车有它自己的方法,我们不会调整制造商的公共(public)属性,但我们仍然无法访问制造商用来制造汽车的技术,所以 car 是黑盒子,暴露了一些 public props,并且不能被调整。
//service for creating/controlling manufactorer
var ManufacturerService = function(companyName) {
var self = this;
self.companyName = companyName;
//encapsulation
var Car = function(name, number){
var createdAt = new Date();
var engineStarts = 0;
//instance property, doesn't have setter
Object.defineProperty(this, 'info', {
get: function(){
return {
name: name,
createdAt: createdAt,
engineStarts: engineStarts
}
}
});
//instance method
this.startEngine = function(){
//private property, available only on instance, and cannot be extracted
engineStarts++;
//reference to ManufacturerService.companyName
console.log(self.companyName + ' ' + name + ':' + number + ' engine Started');
}
}
var createCar = function(name){
//check cache/duplication/validation
//or use custom behavior
var carNumber = ManufacturerService.genShortUid();
return new Car(name, carNumber);
}
var getName = function(){
return self.companyName;
}
return {
getName: getName,
createCar: createCar
}
};
//static method, this can be overriden by 3rdParty or user
ManufacturerService.genShortUid = function genShortUid() {
return ('0000' + (Math.random()*Math.pow(36,4) << 0).toString(36)).slice(-4);
}
用法,ManufacturerService
被编写为插件/库,但请注意 Car 模型是完全封装的,这意味着模型对外界完全隐藏
//create a service instance
var VolvoCompany = new ManufacturerService('Volvo');
//access encapsulated Car model by createCar method
//which is available only on instance of service
var Golf = VolvoCompany.createCar('Golf');
//instance method of car Model
Golf.startEngine(); //logs Volvo Golf:vnv6 engine Started
Golf.info
//returns
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1}
//try to hack car instance
Golf.info.name = 'test';
Golf.name = 'test';
Golf.info
//returns same object, as Car model doesn't have exported setters
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1}
//customize guid generator of ManufacturerService
ManufacturerService.genShortUid = function(){
return '1111';
}
//reuse same service for another Car model
var Mazda = VolvoCompany.createCar('Mazda');
//instance method of car Model
Mazda.startEngine(); //logs Volvo Mazda:1111 engine Started
总结
ManufacturerService
exports 方法数量有限,完全开放,但Car
实例完全封装,甚至不可见
欢迎编辑/建议/评论
关于javascript - 使用javascript函数的三种不同方式,但我不知道它的优缺点。有人可以解释差异吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35378961/