Javascript函数像对象和函数一样
Javascript function acting like object and function
通过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(选项),但定义的属性getOptions
和setLog
丢失了它。
您的目标是哪个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
直接定义方法或者组合它们…
我可以观察到这里有两个不同的用例:
- <
- 获取/设置选项/gh>
- 获取/设置日志相关的东西?
为什么不呢:
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
库。
谢谢
相关文章:
- 是否可以像字符串一样/操作/函数
- 为什么可以'我们在函数体中为函数对象添加属性,就像在javascript中为对象文字添加属性一样
- 使用条件函数的Jquery ReplaceWith()的行为与我预期的不一样
- 为什么javascript函数名称custom是一个小写的单词,后跟一个大写的单词,就像'orangeCost'一样
- 如何使函数像回调一样运行
- 箭头函数是否像命名函数一样进行了优化
- NodeJS-从其他文件导入函数,并像以前一样使用
- Dijkstra's”;针对GOTO声明的案件“;与函数一样适用于现代调用代码的命名封装
- 如何使用字符串引用闭包,就像我在不使用 eval 的情况下使用成员函数一样
- D3 示例:看起来像一个 JavaScript 变量,但像一个函数一样调用
- 当javascript函数更改html输入文本时,我希望输入文本像调用其他JS函数一样触发事件
- jQuery如何像对象和函数一样工作?
- 构建一个可以像函数一样被触发的React组件
- Javascript函数像对象和函数一样
- 像alert()函数一样停止页面执行
- 是否有可能使一个对象在Javascript中调用时像函数一样
- 如何使javascript对象像函数一样被调用
- 为什么在expression4.x中像普通函数一样使用Router而不是构造函数
- 属性怎么像函数一样呢?
- 调用像函数一样声明的对象