Is your Mixin compatible with ecmascript 5?

Source: Internet
Author: User
Tags hasownproperty

Original article: Are your
Mixins ecmascript 5 compatible?

Author: Nicholas C. zakas

Your
Is Mixin compatible with ecmascript 5?

Translator: justjavac

I haven't updated my blog for a long time. Today I saw this blog in nczonline, So I translated it as soon as possible. The level of English is limited. You can refer to the following text:

Ecmascript 5, which I recently worked with clients, needs to be fully utilized. I encountered a very interesting problem here. This problem stems from a very common model:MixinMany articles are translated as "mixed in". I think we should keep the original article. The process is no less than closure. What! You don't know? Please, if you are from Mars, please google it yourself. @ Justjavac ),
That is, in Javascript, the attribute or method of an object is Mixin to another object.

Most Mixin functions look like this:

function mixin(receiver, supplier) {    for (var property in supplier) {        if (supplier.hasOwnProperty(property)) {            receiver[property] = supplier[property];        }    }}

In this Mixin () function, a for loop traverses the properties of the supplier object and assigns a value to the receiver object. Almost all JavaScript libraries have some similar functions, allowing you to write such code:

mixin(object, {    name: "Nicholas",    sayName: function() {        console.log(this.name);    }});object.sayName();       // outputs "Nicholas"

In this example, the object receives the property name and method sayname (). This works well in ecmascript 3, but not so optimistic in ecmascript 5.

This is my problem:

(function() {    // to be filled in later    var name;    mixin(object, {        get name() {            return name;        }    });    // let's just say this is later    name = "Nicholas";}());console.log(object.name);       // undefined

This example looks a bit pretentious, but it accurately describes the problem. The Mixin attribute uses the new feature of ecmascript 5: A getter attribute accesser. Getter references an uninitialized local variable.nameSo this property is not defined
Undefined.

Later, the name is assigned a value so that the accessor getter can return a valid value. Unfortunately, object. Name (the attribute of Mixin) always returns undefined.

What's going on?

We carefully analyze the Mixin () function. In fact, in loop statements, attributes are not re-assigned from one object to another. It actually creates an attribute with the same name, and assigns the returned value of the getter method of the supplier object to it. The target object does not obtain the getter method, but the return value of the getter method. @ Justjavac)

In this example, the Mixin () process is actually like this:

receiver.name = supplier.name;

The property er. Name is created and assigned the value of supplier. Name. Of course, supplier. name has a getter method to return the value of the local variable name. At this time, the value of name is undefined, so the stored er. Name isValue. There is no getter method created for javaser. Name, so its value will never change. I will explain the differences between variables and values in the "puzzle of Code .)

To solve this problem, you need to use the attribute Descriptor (: descriptor) to convert the attribute from an object Mixin to another object. A pure version of ecmascript 5 Mixin () should be written as follows:

function mixin(receiver, supplier) {    Object.keys(supplier).forEach(function(value, property) {        Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));    });}

In this new function, object. Keys () is used to obtain an array that contains all enumeration attributes of the supplier object. Then, the foreach () method is used to traverse these attributes. Call object. getownpropertydescriptor () to obtain each attribute Descriptor (descriptor) of the supplier object ).

Because the descriptor (descriptor) contains all attribute information, including the getter and setter methods, this descriptor can be directly transmitted to the object. defineproperty () is used to create the same attributes on the Explorer Object. Using this new version of Mixin () can solve the previous problems and get the expected results. The getter method is correctly passed from supplier to receiver.

Of course, if you still need to support the old browser, then you need a function to fall back to ecmascript 3:

function mixin(receiver, supplier) {    if (Object.keys) {        Object.keys(supplier).forEach(function(value, property) {            Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));        });    } else {        for (var property in supplier) {            if (supplier.hasOwnProperty(property)) {                receiver[property] = supplier[property];            }        }    }}

If you need to use a Mixin () function, you must carefully check that it works normally in ecmascript 5, especially the getter and setter methods. Otherwise, you will find yourself in the same mistake as me.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.