是否有可能隐藏Javascript对象的原型!这背后的神秘是什么?

iki*_*kiw 5 javascript oop prototype sapui5

我正在使用openui5.有一个UI控件的构造函数Button,无法看到Button的原型属性,但在浏览器控制台中执行时却出现同样的事情,显示出来!

 sap.m.Button.prototype.Move = function(){
  console.log('Move');
} 
var oButton = new sap.m.Button({text:"Hello"});
oButton.Move(); // throws undefined function! 
Run Code Online (Sandbox Code Playgroud)

在控制台中执行浏览器时相同的代码,它的工作原理!

jsbin - > http://jsbin.com/tepum/1/edit

HMR*_*HMR 3

运行代码后,我发现创建 sap.m.Button 的第一个实例会导致脚本更改 sap.m.Button 的原型。它在 JavaScript 中是有效的,但如果你问我的话,它不是很聪明。

第一次创建会导致同步请求(也不是)来获取library-parameters.json。

如果您第二次运行代码,它将具有prototype.move,因为创建Button 实例不会更改Button.prototype。

Move 中的大写 M 表示构造函数,因此我建议将其更改为小写。

由于获取参数是同步的,您可以创建第一个实例,然后设置原型:

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
Run Code Online (Sandbox Code Playgroud)

我的猜测是,这是为了延迟加载控件,如果从未创建 Button,则永远不会为这些未使用的控件加载 json 配置文件。但它有一些缺点。

  1. 您必须先创建一个实例,然后才能设置原型。
  2. 配置文件是同步加载的,因此当使用慢速连接创建许多控件的第一个实例时,会导致应用程序无响应。

更好的方法是工厂函数返回一个承诺,这样您每次都以相同的方式创建控件,并且可以异步获取配置文件。

[更新]

查看配置,它似乎是整个 gui 库的配置,因此我看不出为什么仅在创建第一个实例后才加载它的任何原因。在创建实例时更改其对象定义的库不太容易扩展,因为它是不可预测的。如果它只在第一次创建时更改原型,那么应该没问题,但看起来库的创建者不希望人们扩展它,或者他们不会使对象定义变得不可预测。如果有可用的 api 文档,那么也许可以尝试检查一下。

[更新]

扩展控件的“正确”方法似乎是使用extend