【问题标题】:Difference(s) between lang.mixin and declare.safeMixin? Dojotoolkitlang.mixin 和 declare.safeMixin 之间的区别?道场工具包
【发布时间】:2016-07-26 13:52:24
【问题描述】:

我已经看过documentation,虽然作者提到了不同之处,但我还是不明白。

【问题讨论】:

    标签: javascript dojo mixins


    【解决方案1】:

    我创建了两个小提琴来向您展示 declare.safeMixinlang.mixin 是如何工作的不同案例。

    从 Dojo 代码中提取的关于 declare.safeMixin 的文档:

    此函数用于混合属性,如 lang.mixin 所做的,但它会跳过构造函数属性并装饰函数,如 declare() 所做的。
    它旨在与由 declare 生成的类和对象一起使用。
    与 dojo.safeMixin 混合的函数可以像普通方法一样使用 this.inherited()。
    该函数用于实现由 declare() 生成的构造函数的 extend() 方法。

    从 Dojo 代码中提取的关于 lang.mixin 的文档:

    所有属性,包括函数(有时称为“方法”),不包括在 Object.prototype 中找到的任何非标准扩展,都从源复制/添加到目标。来源从左到右处理。
    Javascript赋值运算符用于复制/添加每个属性;因此,默认情况下,mixin 执行所谓的“浅拷贝”,聚合类型通过引用进行复制/添加。

    增强使用declare 创建的dojo 类:

    可以在here 找到工作示例。您需要打开控制台才能查看日志。

    首先我们声明一个dojo类Person,然后创建这个类的两个实例:

    var Person = declare(null, {
      name: null,
      message: "foo",
      constructor: function(args) {
        this.name = args.name;
      },
      speak: function() {
        console.log(`   ${this.name} says: '${this.message}'!`);
      }
    });
    
    
    var rob = new Person({ name: "Rob" });
    var peter = new Person({ name: "Peter" });
    

    如果我们调用 speak 方法 rob 和 peter 会同时说出 foo

    现在我们用declare.safeMixin修改一个实例(rob)...

      declare.safeMixin(rob, {
        secondMessage: "bar",
        speak: function() {
            this.inherited(arguments);
            console.log(`   ${this.name} says: '${this.secondMessage}'!`);
        }
      });
    

    ...和另一个 (peter) 与 lang.mixin

      lang.mixin(peter, {
        secondMessage: "bar",
        speak: function() {
            // this.inherited(arguments); // would cause an error
            console.log(`   ${this.name} says: '${this.secondMessage}'!`);
        }
      });
    

    之后,Rob 会说两个词,因为我们使用了declare.safeMixin,这说明我们可以在我们的覆盖 speak 方法中使用this.inherited(arguments)

    Peter 只会说一个词而不是 Rob,因为我们使用了 lang.mixin,它完全覆盖我们之前的 speak 方法。

    注意:您可以编写代码,使lang.mixin 也允许使用inherited(您需要在this.inherited 中明确命名要调用的方法) :

    lang.mixin(peter, {
      secondMessage: "bar",
      speak: function() {
          this.inherited('speak', arguments);
          console.log(`   ${this.name} says: '${this.secondMessage}'!`);
      }
    });
    

    有关工作示例,请参阅 here

    增加一个简单的java脚本对象:

    可以在here 找到工作示例。您需要打开控制台才能查看日志。

    首先我们声明两个对象,它们具有相同的属性foo

      var object= {
        foo: "bar"
      };
    
      var anotherObject = {
        foo: "bar"
      };
    

    然后我们再次修改两者。 object 实例与 declare.safeMixin ...

      declare.safeMixin(object, {
        baz: 123
      }, {
        baz: 1234
      });
    

    ... 以及带有lang.mixinanotherObject 实例。

      lang.mixin(anotherObject, {
        baz: 123
      }, {
        baz: 1234
      });
    

    注意,我们在两个实例上混合,两个对象!现在如果我们尝试访问两个实例的baz 属性,我们将得到不同的结果。

    object 实例 baz 属性将返回 123,因为 declare.safeMixin 仅支持在每个方法调用中混入一个 java 脚本对象。

    anotherObject 实例 baz 属性将返回 1234,因为 lang.mixin 支持在每个方法调用中混入多个 java 脚本对象。这里很重要:最后一个获胜。

    希望这能让事情变得更清楚。

    【讨论】:

    • 这就是 javascript(和 Dojo)@Sebastian Frey 的惊人之处
    • 很好解释@ben
    猜你喜欢
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 2010-11-27
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 2015-10-01
    相关资源
    最近更新 更多