20

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.

18
  • 2
    Why do you even use Function instead of an object {} in your code? Commented Oct 17, 2016 at 22:35
  • 1
    It is syntactically correct of course, or you'd get a syntax error when loading the file. JSLint flags it because Crockford didn't think you should create functions like that. Also, I'm with @zerkms; neither of them are doing anything that that you couldn't do with var q = {};. Commented Oct 17, 2016 at 22:36
  • 2
    they do something different. typeof (new Function) === "function", typeof (new function(){}) === "object". Commented Oct 17, 2016 at 22:40
  • 3
    Never ever use new function! Commented Oct 17, 2016 at 22:43
  • 2
    There is so much wrong with both syntaxes. What are you actually trying to do? What result do you need? Is func supposed to be a function? If yes, what should it do when called? And yes, you really could need a Code Review on your original code (at least from what you've shown as an excerpt). Commented Oct 17, 2016 at 22:44

3 Answers 3

21

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.

Sign up to request clarification or add additional context in comments.

3 Comments

…but not an ordinary object like you'd get from evaluating {} or new Object.
Of course, because its constructor will point to the anonymous function passed after new operator, and its prototype chain will contain two prototypes, but it won't contain any other method than with an object created with {} or new Object.
Thanks. Now I started to get the constructor through the comment. I do understand the constructor, but never really placed it into its context with the function.
10

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.

6 Comments

The second function is "anonymous" too. ;-)
@RobG That's true... I guess I meant that the anonymous function was called immediately, instead of assigned and reused later on.
It seems that Function should also be used in a different context, which is to take a string. Wouldn't the source code I posted be wrong at that?
In the context of your code using an object literal, like you did in your edit, is the better approach. What Function allows you to do is compose a function with strings (strings for arguments and for function body) but they lack closures so they can exhibit unexpected behavior.
@RobG In the second example, the function is not anonymous as it's directly assigned to Example: Its name property equals "Example".
|
2

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

9 Comments

I don't think this at all answers the question
"objects created through new Function() are less efficient than the functions created using function expression" --- this needs some scientific evidence.
@zerkms regardless I don't think this is related to the question?
"They are less efficient because object created through Function would return anonymous function where as with expression it returns an object" --- this makes no sense, sorry.
It's less efficient because the constructor takes a string as the function body, and that string would have to be parsed into code, doing some sort of evaluation.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.