了解扩展和方法覆盖

Understanding extend and method overwriting

这是上一个问题的后续问题:Why is the parent prototype method still executable after overriding?

正如我们所见,文字对象{metadata, aaa, init}extend函数初始化为第二个导入变量,所以这个对象应该是自动实例化的对象,代表扩展子class。然后在对象内部,它从其父对象 class 继承了 init 方法并覆盖了它。首先调用parentinit方法来触发一些必要的事情,然后为这个扩展组件设置数据。

我的问题是:这个文字对象中的init方法是它自己的init方法,因为this引用了文字对象,对吧?如果是,为什么我在调试器工具的 this 属性下看不到它。 enter image description here

sap.ui.define([
  "sap/ui/core/UIComponent",
  "sap/ui/model/json/JSONModel",
  "sap/ui/model/resource/ResourceModel",
], function (UIComponent, JSONModel, ResourceModel) {
  "use strict";

  return UIComponent.extend("sap.ui.demo.walkthrough.Component", {
    metadata: {
      "interfaces": [
        "sap.ui.core.IAsyncContentCreation",
      ],
      "rootView": {
        "viewName": "sap.ui.demo.walkthrough.view.App",
        "type": "XML",
        /*"async": true, // implicitly set via the sap.ui.core.IAsyncContentCreation interface*/
        "id": "app",
      },
    },

    aaa: function () {
      console.log("aaa");
    },

    init: function () {
      // call the init function of the parent
      UIComponent.prototype.init.apply(this, arguments);
      // set data model
      var oData = {
        recipient: {
          name: "World",
        },
      };
      var oModel = new JSONModel(oData);
      this.setModel(oModel);
      // set i18n model
      var i18nModel = new ResourceModel({
        bundleName: "sap.ui.demo.walkthrough.i18n.i18n",
      });
      this.setModel(i18nModel, "i18n");
    },

  });
});

希望 this other answer 清除一些东西:

__proto__ is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build __proto__ when you create an object with new

这意味着当您在原型部分看到方法时,并不意味着原来的 parent class 被覆盖了。您的新“class”sap.ui.demo.walkthrough.Component 也 has/is 一个原型和 this(这是您的新“class”的一个实例)有它自己的 __proto__.这个新 prototype/proto 包含形成 parent 原型的方法,也可以定义新方法。

并且来自 sap.ui.base.Object.extend 的文档:

Creates a subclass of class sap.ui.base.Object with name sClassName and enriches it with the information contained in oClassInfo.

oClassInfo might contain three kinds of information:

  • [...]
  • any-other-name: any other property in the oClassInfo is copied into the prototype object of the newly created class. Callers can thereby add methods or properties to all instances of the class. [...]

因此,当您执行 this.__proto 时,您将看到当前实例的构建计划。 执行 this.__proto__.__proto__ 从 parent class 获取构建计划。执行 this.__proto__.__proto__.__proto__ 以获得盛大 parent class(依此类推)。

parent class 的原型不受您的 child class 的影响。但是您的 child classes 包括 parent class 中的所有内容。当您“覆盖”一个方法时,您是在向新原型添加一个方法。 parent 方法仍然存在于 UIComponent 原型中,因此可以通过显式声明 UIComponent.prototype.init.apply.

来调用