原文链接: Jörg Bornemann – Qtified JavaScript
在写JavaScript代码时,用不了多久我就会想念一些Qt C++ API中可用的函数。一个很简单的例子是QList::contains。在JavaScript中,像这样检查一个数组是否含有一个确定的元素:
var names = ["Egon", "Peter", "Raymond", "Waldo"]; if (names.indexOf("Waldo") !== -1) print("We've found him!");
如果我们能够使用cantains方式就好了。但是Array没有提供。
幸运的是,JavaScript允许我们通过修改对应的原型对象为内建类型(inbuilt types)添加方法。
Array.prototype.contains = function(e) { return this.indexOf(e) !== -1; } if (names.contains("Waldo")) print("We've found him!");
耶!现在对于所有数组,我们都可以使用contain方法了。
但是,当您尝试迭代数组的关键字时,有一个潜在的惊奇。
for (var i in names) print(i);
将会打印:
0 1 2 3 contains
我知道数组迭代可以通过索引变量完成……但是……附加的关键字是不可预知的并且会有麻烦。
解决这个问题的方法是把contains属性标记为non-enumerable。我们可以使用Object.defineProperty函数,它是从JavaScript 1.8.5后可用的。
Object.defineProperty(Array.prototype, "contains", { value: function(e) { return this.indexOf(e) !== -1; }, enumerable: false // This is the default and can be omitted. })
我们给Object.defineProperty传递我们想要增强的对象、要添加属性的名字和一个包含我们的新属性的标志描述对象。
contains的值是我们显式直接传递给原型的函数。当使用for (… in …)循环时,把描述对象中的enumerable属性设置为false会隐藏contains。
通过这种方式,我们可以为内建JavaScript类型数组和字符串创建像Qt一样友好的API。这可以放在一个.js文件中并且在QML/JS或者qbs项目文件中使用。
您觉得怎么样?像这样的API对您的QML代码有帮助么?您最想要哪一个QList或者QString方法?