通过API设计我需要这样的东西:
Store = function(fn, args) {
return this[fn](args);
}
Store.getOptions() { return this.options}
Store.setLog(args) { this.options.log = args}
使用单独的选项从商店创建对象实例,例如:
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);
将act表示为对象(创建新对象)并可以调用。
我正在尝试使用Store.bind(选项),但已定义的属性getOptions
和setLog
会丢失它。
答案 0 :(得分:0)
您要定位哪个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()' */ };
注意:类的实例的所有属性和函数都被添加到类构造函数的prototype属性中。 * /
// 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)
中查看有关课程用法的文章答案 1 :(得分:0)
你为什么要这样做?
let opt1 = Store1('getOptions'); //Store acting like a function
Store1('setLogs', false); //same call
只需定义方法或组合它们。
我可以在这里看到你有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
通过这种方式,您可以通过重用原型来组合很多对象。
答案 2 :(得分:0)
首先,感谢@ 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
,并且您还必须添加Ramda
库以用于咖喱功能。
由于