Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've tried to roll out my own HyperScript implementation. I would be interested in any suggestions to improve it or point me to any other better implementation which is still maintained. I checked the HyperScript project, but it doesn't seem to have any recent updates, so I tried this:

var DOM = {
    h: function(tagName, props, children) {
        var element = document.createElement(tagName);
        if (props) {
            for (var item in props) {
                element[item] = props[item];
            }
        }
        if (children && Array.isArray(children) && children.length > 0) {
            children.forEach(function(child) {
                element.appendChild(child);
            });
        }
        return element;
    },
    div: function(props, children) {
        return this.h('div', props, children);
    },
    label: function(props, children) {
        return this.h('label', props, children);
    },
    input: function(props, children) {
        return this.h('input', props, children);
    },
    button: function(props, children) {
        return this.h('button', props, children);
    },
    li: function(props, children) {
        return this.h('li', props, children);
    }
};

Usage:

DOM.button({ className: "destroy" });
share|improve this question

The fun thing about these kinds of libraries is that they're fun to implement. The sad thing about them is that they aren't really fun to work with. You will beg for markup-like syntax in the long run.

But anyways,

div: function(props, children) {
    return this.h('div', props, children);
},
label: function(props, children) {
    return this.h('label', props, children);
},
input: function(props, children) {
    return this.h('input', props, children);
},
button: function(props, children) {
    return this.h('button', props, children);
},
li: function(props, children) {
    return this.h('li', props, children);
}

This can be simplified into a list of element names. You can run through it and assign a function to DOM for each name.

['div', 'li', ...].forEach(elementName => {
  DOM[elementName] = function(props, children){
    return this.h(elementName, props, children);
  };
});

As for your h function, you should guard for-in with hasOwnProperty to avoid iterating over prototype elements. Alternatively, you can use Object.keys and forEach. Also, silencing errors is terrible when debugging. If the user passed in something not an array, best inform them immediately. In the following code, it only catches on falsy values. Anything else, like a non-array or something will throw because forEach expects an array.

h: function(tagName, props, children) {
    var element = document.createElement(tagName);

    Object.keys(props || []).forEach( prop => {
      element[prop] = props[prop];
    });

    (children || []).forEach(child => {
      element.appendChild(child);
    });

    return element;
},
share|improve this answer
    
You won't believe that I tried that but for some reason, document.createElement("div").hasOwnProperty("className") is evaluating to false. How is that even possible? – Soham Dasgupta Feb 20 at 5:17
1  
@SohamDasgupta You are looping through props. You use hasOwnProperty on props, not the element. – Joseph the Dreamer Feb 20 at 14:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.