salambshr
salambshr

Reputation: 73

Difference(s) between lang.mixin and declare.safeMixin? Dojotoolkit

I have already read the documentation , even though the author has mentioned the differences , I still don't get it .

Upvotes: 1

Views: 1243

Answers (1)

Sebastian Frey
Sebastian Frey

Reputation: 488

I created two fiddles to show you different cases of how declare.safeMixin and lang.mixin are working.

Documentation extracted from Dojo code about declare.safeMixin:

This function is used to mix in properties like lang.mixin does, but it skips a constructor property and decorates functions like declare() does.
It is meant to be used with classes and objects produced with declare.
Functions mixed in with dojo.safeMixin can use this.inherited() like normal methods.
This function is used to implement extend() method of a constructor produced with declare().

Documentation extracted from Dojo code about lang.mixin:

All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.

Augmenting a dojo class created with declare:

Working example can be found here. You need to open the console to view the logs.

First we declare a dojo class Person and then create two instances of this class:

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" });

If we call the speak method rob and peter will say both foo.

Now we modify one instance (rob) with declare.safeMixin ...

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

... and the other one (peter) with lang.mixin.

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

After that, Rob will say two words, because we used declare.safeMixin, which annotates that we can use this.inherited(arguments) in our overriden speak method.

Instead of Rob, Peter will say only one word, because we used lang.mixin, which completly overrides our earliere speak method.

Note: You can write your code in a such way that lang.mixin allows to use inherited as well (you need to explicitly name the method you want to call in this.inherited):

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

See here for a working example.

Augmenting a simple java script object:

Working example can be found here. You need to open the console to view the logs.

First we declare two objects, which have the same property foo.

  var object= {
    foo: "bar"
  };

  var anotherObject = {
    foo: "bar"
  };

Then again we modify both. The object instance with declare.safeMixin ...

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

... and the anotherObject instance with lang.mixin.

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

Note, that we mixin on both instances, two objects! Now if we try to access the baz property of both instances, we will get different results.

The object instances baz property will return 123, because declare.safeMixin only supports mixin one java script object per method call.

The anotherObject instances baz property will return 1234, beacuse lang.mixin supports mixin multiple java script objects per method call. Here counts: last one wins.

Hope this makes things a little bit clear.

Upvotes: 4

Related Questions