这种链接在 JavaScript 中是否可行
Is this kind of chaining possible in JavaScript?
我正在开发一个类似于elFinder的文件管理器框架。我当前的代码工作正常,但现在我想让它看起来更好并添加链接(我不确定它是链接还是装饰器模式)。
以下是我想做的事情的示例:
function UI() {}
UI.prototype.folders = function(){
return [];
}
UI.prototype.folders.prototype.getSelectedFolder = function(){
return {};
}
调用UI.folders()
应返回文件夹对象的数组。因此,如果您致电UI.folders()
,您会得到类似以下内容:
[
Object { name="folder1", selected=false },
Object { name="folder2", selected=false },
Object { name="folder3", selected=true }
]
调用UI.folders().getSelectedFolder()
将过滤UI.folders()
的结果并返回:
Object { name="folder3", selected=true }
这可能吗?在这种情况下说"链式"还是"装饰图案"是正确的?
如果不是 - 有没有其他更合适的方法?
任何帮助将不胜感激!
您问题中的代码并不反映正确的实现,但要回答您的直接问题,是的,这个...
UI.folders().getSelectedFolder()
。将是方法链接的一个例子。
装饰器模式是不同的。如果你有一组方法,并且每个方法都应该首先调用一些公共函数,你可以创建一个装饰器,它将返回一个函数,该函数首先调用公共函数,然后调用实际函数......
function foo() {
console.log('I''m foo, and I''m first, and I was given these args:', arguments);
}
function decorateWithFoo(decorated) {
return function () {
foo.apply(this, arguments);
decorated.apply(this, arguments);
};
}
因此,您可以使用decorateWithFoo
创建一个始终首先调用foo
的函数...
// create and decorate bar()
var bar = function(a,b) {
console.log('I''m bar, and I was called after "foo", and was given args:', a, b);
};
bar = decorateWithFoo(bar);
bar(123, 456); // this will first call `foo()`, then (the original) `bar()`.
// create and decorate baz()
var baz = function(a,b) {
console.log('I''m baz, and I was called after "foo", and was given args:', a, b);
};
baz = decorateWithFoo(baz);
baz(123, 456); // this will first call `foo()`, then (the original) `baz()`.
某些语言具有用于创建装饰器的内置语法。JavaScript 目前没有。
如果您发现自己以不同的方式使用装饰器,则可以创建另一个函数来设置初始装饰器函数...
function generateDecorator(decorator) {
return function (decorated) {
return function () {
decorator.apply(this, arguments);
decorated.apply(this, arguments);
};
};
}
所以我们原来的decoreateWithFoo
可以这样设置......
function foo() {
console.log('I''m foo, and I''m first, and I was given these args:', arguments);
}
var decorateWithFoo = generateDecorator(foo);
为了使它正常工作,您需要使文件夹方法成为返回从数组继承的对象的函数。
UI.prototype.folders = function(){
// must return an object that inherits from an array
// that has the additional methods on it you want like getSelectedFolder()
}
有几种不同的方法可以解决这个问题。 主要目标是,当你调用一个函数时,你会得到一个对象/函数,它是具有不同属性的相同类型的对象。 我不喜欢原型的使用,所以我会这样做(这是解决它的一种方法):
var FolderList = function ()
{
var _folders = [];
folders.pop({ name: "folder1", selected: false });
folders.pop({ name: "folder2", selected: true });
folders.pop({ name: "folder3", selected: false });
// prevent other programers from changing _folders
// which would break this, so just use a function
this.folders = function ()
{
return _folders;
}
this.selectedFolders = function ()
{
var tmpFolders = [];
for (var folderIndex = 0;
folderIndex < this._folders.length;
folderIndex++)
{
if (this._folders[folderIndex].selected)
{
tmpFolders.pop(_folders[folderIndex]);
}
}
_folders = tmpFolders;
return this;
}
this.addFolder = function (folder)
{
_folders.pop(folder);
return this;
}
};
var folderList = new FolderList();
folderList.selectedFolders()
.addFolder({ name: "folder1", selected: false })
.addFolder({ name: "folder3", selected: true })
.selectedFolders();
// array of 2 objects, folder2 and folder3
var arrayOfSelectedFolder = folderList.folders();
相关文章:
- 是否可以控制获取哪些Google地图脚本(JavaScript API)
- 用于检查数组中是否存在元素的javascript自定义方法
- 是否可以在浏览器中使用纯JavaScript保存音频流
- 是否可以使用JavaScript/AAJAX在客户端创建一个文件
- 我是否可以检测到javascript正在被卸载(作为调试模式)
- PhantomJS - 检查javascript函数是否正在运行的任何方法
- 是否有任何JavaScript UI组件可以显示字符串之间的差异
- javascript跨浏览器确定用户是否滚动到页面底部
- 是否可以用JavaScript显示等效的文件夹对话框
- 检查是否存在使用chrome扩展的javascript库
- 如何知道javascript for语句中的所有结果是否都是错误的
- 是否存在Javascript Liferay Service库的文档?如何处理错误情况
- 是否可以使用jquery或javascript将自动增量类添加到列表中
- javascript移动交叉浏览器确定用户是否滚动到页面底部
- 有没有一种方法可以从Javascript检测特定的应用程序是否安装在(AndroidiOS)设备上
- javascript数组元素是否知道其封闭数组
- 是否“;对于的“;循环迭代遵循JavaScript中的数组顺序
- 是否有任何设置阻止JavaScript在系统上工作
- 是否可以在javascript中读取IE中的本地文件
- 是否有任何Javascript函数从指定的索引中进行正则表达式匹配