我正在使用 openui5。有一个UI控件Button的构造函数,看不到Button的prototype属性,但是在浏览器控制台中执行时出现了同样的东西!
sap.m.Button.prototype.Move = function(){
console.log('Move');
}
var oButton = new sap.m.Button({text:"Hello"});
oButton.Move(); // throws undefined function!
在控制台中执行浏览器时相同的代码,它有效!
jsbin --> http://jsbin.com/tepum/1/edit
最佳答案
运行代码后,我发现创建 sap.m.Button 的第一个实例会导致脚本更改 sap.m.Button 的原型(prototype)。它在 JavaScript 中有效,但如果你问我,它不是很聪明。
第一次创建会导致同步请求(也不是 no)来获取 library-parameters.json。
如果您第二次运行代码,它将具有 prototype.move,因为创建 Button 的实例不会更改 Button.prototype。
Move 中的大写 M 表示构造函数,因此我建议将其更改为小写。
由于获取参数是同步的,您可以创建第一个实例,然后设置原型(prototype):
console.log("First Button creation changes Button.prototype");
var oButton = new sap.m.Button({text:"Hello"});
sap.m.Button.prototype.move = function(){
console.log('Move');
}
oButton.placeAt('content');
oButton.move(); // logs Move
我的猜测是,这是为了延迟加载控件,如果从未创建 Button,则永远不会为这些未使用的控件加载 json 配置文件。但它有几个缺点。
- 您必须先创建一个实例,然后才能设置原型(prototype)。
- 配置文件是同步加载的,因此在创建连接速度较慢的许多控件的第一个实例时会导致应用无响应。
更好的方法是让工厂函数返回一个 promise ,这样您每次都以相同的方式创建控件,并且可以异步获取配置文件。
[更新]
查看配置,它似乎是整个 gui 库的配置,所以我看不出为什么只在创建第一个实例后才加载它。在创建实例时更改其对象定义的库不容易扩展,因为它是不可预测的。如果它只是在第一次创建时更改原型(prototype)那么它应该没问题,但看起来库的制造者不希望人们扩展它或者他们不会使对象定义不可预测。如果有可用的 api 文档,则可能会尝试检查一下。
[更新]
扩展控件的“正确”方法似乎是使用 extend .
关于oop - 是否可以隐藏 Javascript 对象的原型(prototype)!这背后的奥秘是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23005462/