javascript - 使用javascript函数的三种不同方式,但我不知道它的优缺点。有人可以解释差异吗?

标签 javascript

我有三种创建函数并返回它的方法。 (也许还有更多?)但我不知道它们之间的区别以及何时使用哪个。 有人可以解释一下吗。

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/

相关文章:

javascript 将许多空间折叠成一个,如 HTML?奇怪的行为

java - 使用 RingoJs 模拟浏览器

javascript - 使用 javascript/jquery 获取复杂嵌套 JSON 的各层数据

javascript - Angular 如何使用 ng-click 从 S3 Amazon 下载文件

javascript - 为什么我的对象被声明但从未读取(在函数内)?

javascript - 从多选中的选定选项中获取属性值

javascript - 如何在 JavaScript 中的嵌入 HTML 中创建 if 语句以显示 CSS 类

javascript - jQuery:链接动画和 AJAX 请求

javascript - 使用 React 动态加载样式表

javascript - React 应用程序中的路由问题