Daniel
Daniel

Reputation: 4946

new function(){} vs new Function();

I picked up some code and I am just getting to understand the new Function();. Going through jslint the new Function(); was highlighted as unexpected. I started to experiment with it doing the following.

var func = new Function();
func.property = "some property";
return func;

A replacement.

var func = new function(){
this.property = "some property";
}
return func;

Both work and the second one is neglected by js-lint.

Am I doing anything spectacular here, or is this exactly the same? Is it syntactical correct to use new Function(); like this?

Original code excerpt is attached.

 var $ = (function() {

   function doCSS(prop, val) {
     var isSet = Boolean(val),
       action = CSSStyleDeclaration.prototype.setProperty,
       args = arguments;
     if (isSet) {
       this.each(function(node, i) {
         action.apply(node.style, args);
       });
       return this;
     } else if (typeof(prop) === 'object') {
       this.each(function(node, i) {
         Object.keys(prop).forEach(function(property) {
           node.style[property] = prop[property];
         });
       });
       return this;
     } else {
       return this.nodes[0].style[prop];
     }
   }



   // chaining of methods
   return (function(selector, context) {
     var q = new Function();
     q.selector = selector;
     q.context = context || document;
     q.nodeList = q.context.querySelectorAll(selector);
     q.each = function(action) {
       [].forEach.call(q.nodeList, function(item, i) {
         action(item, i);
       });
       return this;
     };
     q.click = function(action) {
       [].forEach.call(q.nodeList, function(item, i) {
         item.addEventListener("click", action, false);
       });
       return this;
     };
     q.toString = function() {
       return q.selector;
     };
     q.css = function(prop, val) {
       return doCSS.call(this, prop, val);
     };


     return q;


   });
 })

Is any of these two wrong in syntax?

EDIT After getting some of the great advice I adapted the code to the following:

var $ = (function($) {

  function doCSS(prop, val) {
    var isSet = Boolean(val),
      action = CSSStyleDeclaration.prototype.setProperty,
      args = arguments;
    if (isSet) {
      this.each(function(node, i) {
        action.apply(node.style, args);
      });
      return this;
    } else if (typeof(prop) === 'object') {
      this.each(function(node, i) {
        Object.keys(prop).forEach(function(property) {
          node.style[property] = prop[property];
        });
      });
      return this;
    } else {
      return this.nodes[0].style[prop];
    }
  }

  // chaining of methods
  return (function(selector, context) {
    var element = context || document;
    var q = {
      selector: selector,
      nodeList: element.querySelectorAll(selector),
      each: function(action) {
        [].forEach.call(this.nodeList, function(item, i) {
          action(item, i);
        });
        return this;
      },
      click: function(action) {
        [].forEach.call(this.nodeList, function(item, i) {
          item.addEventListener("click", action, false);
        });
        return this;
      },
      toString: function() {
        return selector;
      },
      css: function(prop, val) {
        return doCSS.call(this, prop, val);
      },

    }

    return q;

  });


})($);

$("#myElement").css({
  background: "blue",
  color: "#fff"
});
<div id="myElement">Say Hi</div>

It works just fine and looks a lot cleaner. JS Lint is nice to me and I can tackle the next issue.

Upvotes: 20

Views: 25326

Answers (3)

kube
kube

Reputation: 13954

In the first case, you create a new object and you apply the Function constructor.

Return value is a function.

In the second example, you create a new object and you apply an anonymous function as constructor.

Return value is an object.

Upvotes: 21

Jorge Cabot
Jorge Cabot

Reputation: 191

Both statements are indeed different. I will focus on the second statement to point out the difference.

var newObj1 = new function () {
    this.prop1 = "test1";
    this.prop2 = "test2"
};

Is equivalent to the following:

var Example = function () {
    this.prop1 = "test1";
    this.prop2 = "test2"
};

var newObj2 = new Example();

The only difference being that in the first example the constructor function called is an anonymous function. Note, that when a function is called with the new keyword in javascript it exhibits special behavior.

In your first statement the constructor function called is an already defined function, Function.

As has been pointed out your first statement returns a function while the second returns an object. Neither, is wrong but one returning a function and the other an object could have implications in other sections of your code.

Upvotes: 10

Geeky
Geeky

Reputation: 7496

Yes it is not right approach to create objects because objects created through new Function() are less efficient than the functions created using function expression

The global Function object has no methods or properties of its own, however, since it is a function itself it does inherit some methods and properties through the prototype chain from Function.prototype

for more reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

Hope this helps

Check the following code snippet

var func = new Function();
func.property = "some property";
"some property"
console.log(func);

now when you check in the console it says it as anonymous but when an object created through function expression

var func=new function(){this.x=10;}
console.log(func);
this returns an objects I guess you understand the difference

Upvotes: 2

Related Questions