Javascript函数像对象和函数一样

Javascript function acting like object and function

本文关键字:函数 一样 对象 Javascript      更新时间:2023-09-26

通过API设计,我需要这样的东西:

Store = function(fn, args) {
     return this[fn](args); 
}
Store.getOptions() { return this.options}
Store.setLog(args) { this.options.log = args}

从Store中创建具有单独选项的对象实例,例如:

option1 = {save:false, log: true}
Store1 = new -->  Store(option1)  //pseudo code object creation
let opt1 = Store1('getOptions');   //Store acting like a function
Store1('setLogs', false);          //same call
Store1.setLogs(false);

Store的行为类似于对象(创建新对象),并且可以调用。

我正在尝试与Store.bind(选项),但定义的属性getOptionssetLog丢失了它。

您的目标是哪个EcmaScript版本:EcmaScript 5或EcmaScript 6 (EcmaScript 2015)?

EcmaScript 5类创建:

// Declare constructor for class Store:
var Store = function(){ /* This code will be executed when you call 'new Store()' */ }; 

:类实例的所有属性和函数都添加到类构造函数的原型属性中。*/

// Add properties for each instance of class Store:
Store.prototype.options = {Hi:'World'}; // Each instance of Store will have object with property Hi:'World'
// Add functions for each instance of class Store:
Store.prototype.SayHello = function(name){
    console.log('Hello ', name);
};

用法:

var store1 = new Store();
store1.SayHello('Phillip'); //Will output: Hello Phillip

EcmaScript 6 (EcmaScript 2015)

查看有关Mozilla Developer Network中类使用的文章

你为什么要这么做?

let opt1 = Store1('getOptions');   //Store acting like a function
Store1('setLogs', false);          //same call

直接定义方法或者组合它们…

我可以观察到这里有两个不同的用例:

    <
  1. 获取/设置选项/gh>
  2. 获取/设置日志相关的东西?

为什么不呢:

var optionsProto = function() {
  var options = [];
  var getOption = function getOption(key) {
    if(options[key]) {
      return options[key];
    }
    //Handle error or return undefined..
  };
  var setOption = function setOption(key, val) {
    if(!options[key]) {
      options[key] = val;
    }
    //It already exists? Handle it somehow
  };
  return {
    getOption: getOption,
    setOption: setOption
  };
}();
var debuggerProto = function() {
  var level = 'DEBUG';
  var getLevel = function getLevel() {
    return level;
  };
  var setLevel = function setLevel(_level) {
    level = _level;
  };
  return {
    getLevel: getLevel,
    setLevel: setLevel
  };
}();

var mixedUpStoreProto = _.extend({}, optionsProto, debuggerProto);
var store = Object.create(mixedUpStoreProto);
store.setLevel('INFO');
store.getLevel(); //INFO
store.addOption('somekey', 'someval');
store.getOption('somekey'); // someval

首先,感谢@Epsil0neR和@gor181的答案,但可能比我不正确做问题。实际上,我再次询问Ramda Github问题,因为我需要用curry函数实现API。最后,我晚了好几个小时才走。

下面是代码,可能对某些人有用:https://github.com/ramda/ramda/issues/1291

//return 'fn' with all 'obj' props
function functionize(obj, fn)
{
    let fn = fn;
    for( let i in obj ){ fn[i] = obj[i] };
    return fn;
}

SubStore = function(options) {
    this.options = options;
}
SubStore.prototype.getOptions = function() { return this.options }
SubStore.prototype.setOptions = function(options) { this.options = options }
SubStore.prototype.insert = function(doc) { return doc }
SubStore.prototype.find = function(selector, options) { return selector }
SubStore.create = function(options) {
    let sub = functionize(new SubStore(options), R.curry(function (args, fn) {
        let self = sub;         //reference to new SubStore obj
        return self[fn](args);
    }))
    return sub;
}
Store = function(options) {
    this.options = options;
}
Store.prototype.insert = function(args) {
    for (let i = 0, len = args.length; i < len; i++) {
        if ( R.is(Function, args[i]) ) { args[i] = args[i]('insert') }
        console.log(args[i]);
    }
}
Store.prototype.find = function(args) {
    for (let i = 0, len = args.length; i < len; i++) {
        if ( R.is(Function, args[i]) ) { args[i] = args[i]('find') }
        console.log(args[i]);
    }
}

测试代码

store = new Store();
sub1 = SubStore.create({path:'perfil'});
sub2 = SubStore.create({path:'rol'});
// test#1
store.insert([ sub1({name: "Foo"}), sub2({age: 18}) ]);
// test#2
store.insert([ sub1.insert({name: "Foo"}), sub2.insert({age: 18}) ]);

如果您需要Javascript ES5版本,只需将let替换为var,并且您必须为curry功能添加Ramda库。

谢谢