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

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.

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.

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.

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

Related

jQuery object data structure

I'm trying to create a mini jQuery clone that can support method chaining. So far I've came up with this piece of code:
var $ = (function () {
var elements = [];
function methodOne() {
console.log('Method 1');
return this;
}
function methodTwo() {
console.log('Method 2');
return this;
}
return {
methodOne: methodOne,
methodTwo: methodTwo
};
}());
At page load, the $ variable gets populated with the jQuery clone object returned by the IIFE.
My question is, how can I make the $ object to be called directly as a function while still maintaining the method chaining functionality?
Right now, I can use $.methodOne().methodTwo() but I cant use $('some parameter').methodOne().methodTwo() just like jQuery does.
var $ = function (param) {
var elements = [];
console.log(param);
function methodOne() {
console.log('Method 1');
return this;
}
function methodTwo() {
console.log('Method 2');
return this;
}
return {
methodOne: methodOne,
methodTwo: methodTwo
};
};
$('This is a param').methodOne().methodTwo();
Working fiddle. The comments should be more or less self explanatory.
It might look a bit long, but it will let you create new mini jQuery object every time you call it.
var _ = (function () {
var Magic = function(query){
if(window === this)
return new Magic(query);
// reference to itself
var that = this;
//assign pseudo public methods and variables
that.elements = [];
that.methodTwo = methodTwo;
that.methodOne = methodOne;
//fills inner element array with DOM element
_get(query);
function _get(query){
var elem = document.getElementById(query);
that.elements.push(elem);
}
function methodOne() {
console.log('Method 1');
return that;
}
function methodTwo() {
console.log('Method 2', that.elements);
return that;
}
return this;
}
//returns function, which is assigned to a "_" variable
return function(query){
//everytime "_" is called, it will return new instance for object Magic which makes all the work
return new Magic(query);
}
}());

Chain non-jquery methods in a jquery plugin

Let's say I write a jquery plugin that has a method that adds two values and sets the html to that value. I can chain it one way, but not the other and I want to understand why, and how I can make sure I can chain both ways.
$.fn.foo = function() {
this.result = 0;
this.doMath= function(a, b) {
this.result = a + b;
this.html(this.val);
return this;
}
return this;
}
var link = 'Link'
// works as expexted
var a = $(link).foo().doMath(1,2).appendTo('body')
// does not work, likely because appendTo returns jquery
var b = $(link).foo().appendTo('body').doMath(1,2)
https://jsfiddle.net/j7ut1f30/1/
After 2 weeks of trying everything, I finally acheived my goals.
class $Util {
static $wrapper(self) {
if (!self.$wrapper)
throw new ReferenceError('$Util.$wrapper: $wrapper not defined in context of first argument');
$.each($Util.jqueryPrototype, function(i, e) {
self[e] = function() {
self.$wrapper[e](...arguments);
return self;
}
});
}
}
$Util.jqueryPrototype = Object.getOwnPropertyNames($.prototype);
class foo {
constructor() {
this.$wrapper = $('p')
$Util.$wrapper(this);
return this;
}
test() {
console.log('j')
return this;
}
}
var s = new foo();
s.css('color', 'red').test().appendTo('body').test().css('color','green')
https://jsfiddle.net/24r6uxs1/

A native way of adding custom JavaScript functions into a method-calls chain

I would like to known if there is a native way of doing this :
Object.prototype.chain = function(f) { return f.call(this) }
function fun1() {
doSomethingWithObject(this)
return this
}
function fun2() {
doSomethingElse(this)
return this
}
someObject
.method1('something')
.method2()
.chain(checkSomething() ? fun1 : fun2)
.method3()
But I do not feel like changing the prototype of Object. Is there a way to do this without modifying the prototype of Objects or the other constructors that I use (and am not the developer of)
Edits :
I feel I do not explain very well, so let' add some details :
What I would like to do is to use some APIs I do not define. someObject is defined like the following, with chainable methods :
var someObject = {
method1: function(val) {
// do something
return this
},
method2: function() {
// do something
return this
},
method3: function() {
// do something
return this
}
}
Now imagine I cannot change this code, because this object is from a library, and so I don't want to. Then, imagine that I would like to chain methods and some custom functions (see my first snippet) for many more different objects. The simplest thing to do is to attach a chain method to Object.prototype.
But I think that it could result in conflicts in the future. I am looking for a way to do the same thing without touching the prototype.
I'm surprised there are no answers to this to be honest.
There are many ways to natively introduce chaining. I like to use the revealing module pattern.
So I create a basic model (Go ahead and chuck this in your chrome of firefox console)
var Dog = function(name) {
var self = this;
this.name = name;
var core = {
getName:function(){
return self.name;
}
};
this.movement = function(){ //this function will be exposed including its returned functions for chaining
console.log(self.name + " is getting restless... ");
var jump = function(){
console.log(self.name + " jumps around ");
return this //returns the movement scope
};
var run = function(){
console.log(self.name + " has decided to run");
return this //returns the movement scope
};
return {
jump:jump,
run:run
};
}
console.log("A Pup has been born, we shall call him... " + name);
return{
movement:self.movement //only .movement is exposed to the outside world
};
}
Now create a new dog using var p = new Dog("doggyName");
now, you can chain functions. Try:
p.movement().jump().run().jump().run();
You should get the console logged text that corresponds with each function.
By returning the scope of this after executing your movement function you expose the additional functions that are returned in that scope (see the comments in the code). These can then be chained onto the end of your current function provided they are in the same scope. This allows you to scope specific parts of your code. For example with this dog, all movement is scoped to self.movement, you could have all eating scoped to self.eat and so on
Read up on the revealing module pattern. Though this is not the only way to do it.
The wrapper is something that will wrap any object to make it compatible with "chaining" and will add another chain method that will allow you to plug external functions and still get the chaining.
Check this example:
function myObj() {
this.state = {
a: 1
};
this.method1 = function () {
console.log("1");
}
this.method2 = function () {
console.log("2");
}
this.method3 = function () {
console.log("3");
}
this.method4 = function () {
console.log(this.state);
}
}
function objectChainWrapper(obj) {
this.chain = function (fn) {
fn.call(obj);
return this;
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
this[prop] = (function (methodName) {
return function () {
obj[methodName].call(obj);
return this;
}
}(prop))
}
}
}
var obj = new myObj();
var wrapper = new objectChainWrapper(obj);
var chainMethod = function(){ console.log('chain') };
var chainMethodState = function(){ console.log(this.state) };
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4();
JSFIDDLE.
To "plug" an unbound function into the object's method chain you can assign it to a property and call that:
function fn() {
document.write('hi ');
return this;
}
someObj = {
meth1: function() {
document.write('meth1 ');
return this;
},
meth2: function() {
document.write('meth2 ');
return this;
}
}
someObj
.meth1()
[someObj._=fn, '_']()
.meth2()
This doesn't look very pretty if you ask me. A more readable option is to add the chain method on the fly, like:
function chainable(obj) {
obj.chain = function(fn) {
return fn.call(this);
}
return obj;
}
chainable(someObj).meth1().chain(fn).meth2()

Rewiring a JavaScript function

Let's say I have a function named fna() that does a simple thing such as:
var fna = function(ar) {
console.log("argument: ", ar);
return "return value is argument too: " + ar;
}
fna() is coded by some other developer and I can't access to it. He didn't bother casting any events and when it is called, I have to be aware of it. Hopefully, his method is accessible by window.fna().
I want some additional code to be executed. Let's say, add this console.log
var fna = function(ar) {
console.log("Hola, I am some additional stuff being rewired");
console.log("argument:", ar);
return "return value is argument too: " + ar;
}
And I want this to be executed even when called from fnb() by some other part of the code.
var fnb = function() {
return fna("Bonjour, I am fnb and I call fna");
}
Here is a way I found, using the utils.rewire() method. utils is just some utility belt, and it could be added to your favorite framework as a plugin. Unfortunately, it only works on Firefox.
var utils = utils || {};
// Let's rewire a function. i.e. My.super.method()
utils.rewire = function(functionFullName, callback) {
var rewired = window[functionFullName];
console.log("%s() is being rewired", functionFullName)
window[functionFullName] = function() {
callback();
return rewired.apply(this, arguments);
}
}
Use it like this.
utils.rewire("fna",function(){
console.log("Hola, I am some additional stuffs being rewired");
});
This seems to work such as shown in this jsbin, but (and here is my question:) How do I rewire obja.fna()?
var obja = {
fna = function(ar) {
console.log("argument:", ar);
return "return value is argument too: " + ar;
}
};
I cannot make it work to rewire the some.object.method() method.
Extra bonus question: Is there a more cleaner way to do this? Out-of-the-box clean concise and magic library?
Refactor rewire into a rewireMethod function which acts on any given object:
var utils = utils || {};
utils.rewireMethod = function (obj, functionName, prefunc) {
var original = obj[functionName];
obj[functionName] = function () {
prefunc();
return original.apply(this, arguments);
};
};
Note that rewire can now be written as:
utils.rewire = function (functionName, prefunc) {
utils.rewireMethod(window, functionName, prefunc);
};
Then you just call it as:
utils.rewireMethod(obja, "fna", function () {
console.log("Hola, I am some additional stuff being rewired");
});
Note that nothing special is required if you have a method like window.ideeli.Search.init(). In that case, the object is window.ideeli.Search, and the method name is init:
utils.rewireMethod(window.ideeli.Search, "init", function () {
console.log("Oh yeah, nested objects.");
});
Add a parameter to rewire that is the object containing the function. If it's a global function, pass in window.
var utils = utils || {};
// let's rewire a function. i.e. My.super.method()
utils.rewire = function(object, functionName, callback) {
var rewired = object[functionName];
console.log("%s() is being rewired", functionName)
object[functionName] = function() {
callback();
return rewired.apply(this, arguments);
}
}
utils.rewire(some.object, "method", function(){} );
You can simply use a closure to create a generic hook function that allows you to specify another function to be called immediately before or after the original function:
function hookFunction(fn, preFn, postFn) {
function hook() {
var retVal;
if (preFn) {
preFn.apply(this, arguments);
}
retVal = fn.apply(this, arguments);
if (postFn) {
postFn.apply(this, arguments);
}
return retVal;
}
return hook;
}
So, for any function that you want to hook, you just call hookFunction and pass it the function you want to hook and then an optional pre and post function or yours. The pre and post function are passed the same arguments that the original function was.
So, if your original function was this:
var fna = function(ar) {
console.log("argument:",ar);
return "return value is argument too:"+ar;
}
And, you want something to happen every time that function is called right before it's called, you would do this:
fna = hookFunction(fna, function() {
console.log("Hola, I am some additional stuff being rewired right before");
});
or if you wanted it to happen right after the original was called, you could do it like this:
fna = hookFunction(fna, null, function() {
console.log("Hola, I am some additional stuff being rewired right after");
});
Working demo: http://jsfiddle.net/jfriend00/DMgn6/
This can be used with methods on objects and arbitrary nesting levels of objects and methods.
var myObj = function(msg) {
this.greeting = msg;
};
myObj.prototype = {
test: function(a) {
log("myObj.test: " + this.greeting);
}
}
var x = new myObj("hello");
x.test = hookFunction(x.test, mypreFunc2, myPostFunc2);
x.test("hello");
Based on Claudiu's answer, which seems to be the most appreciated way, here is a solution using a for loop and proxying the context... But still, I find this ugly.
var utils = utils || {};
// Let's rewire a function. i.e. My.super.method()
utils.rewire = function(method, callback) {
var obj = window;
var original = function() {};
var tree = method.split(".");
var fun = tree.pop();
console.log(tree);
// Parse through the hierarchy
for (var i = 0; i < tree.length; i++) {
obj = obj[tree[i]];
}
if(typeof(obj[fun]) === "function") {
original = obj[fun];
}
var cb = callback.bind(obj);
obj[fun] = function(ar) {
cb();
return original.apply(this, arguments);
}
}
Well, this looks strange. Consider this
function wrap(fn, wrapper) {
return function() {
var a = arguments;
return wrapper(function() { return fn.apply(this, a) })
}
}
Example:
function foo(a, b) {
console.log([a, b])
return a + b
}
bar = wrap(foo, function(original) {
console.log("hi")
var ret = original()
console.log("there")
return ret
})
console.log(bar(11,22))
Result:
hi
[11, 22]
there
33
To wrap object methods, just bind them:
obj = {
x: 111,
foo: function(a, b) {
console.log([a, b, this.x])
}
}
bar = wrap(obj.foo.bind(obj), function(fn) {
console.log("hi")
return fn()
})

Assigning multiple methods to an application in JavaScript

I have now officially spent all day trying to assign a variable in JavaScript!
Forgive me for asking this same question 4 different ways, but here's what I started out with this morning, and this works. I just need to add a second method to it now.
Application = {};
(function() {
var closure = {};
Application.myFirstMethod = function() {
if (arguments.length) {
closure = arguments[0];
} else {
return closure;
}
}
})();
Application.myFirstMethod(3.14);
result = Application.myFirstMethod();
log(result);
So my question is: and please be patient with me, if I add mySecondMethod to Application, then how do I keep the value of arguments[0] without using the variable that is currently called closure?
How about this, it defines a function that takes a string and returns a getter/setter function. The string is used to indicate what property to get/set the value as in variables.
Demo
Application = {};
(function() {
var variables = {};
Application.myFirstMethod = makeGetterSetter('myFirst');
Application.mySecondMethod = makeGetterSetter('mySecond');
function makeGetterSetter(name) {
return function () {
if (arguments.length) {
variables[name] = arguments[0];
} else {
return variables[name];
}
};
}
})();
Application.myFirstMethod(4);
result1 = Application.myFirstMethod();
Application.mySecondMethod(5);
result2 = Application.mySecondMethod();
console.log(result1);
console.log(result2);
If you wanted to have a getter or setter with custom logic in it before either event then it would be easiest to just define them separately. Stick with the this[property] pattern to keep all your fields in one spot.
Application.myCustomMethod = function() {
if (arguments.length) {
// some logic
variables['custom'] = arguments[0];
} else {
// some logic
return variables['custom'];
}
}
It looks like you are searching for adding properties to objects, in the Prototype-Oriented Programming Language sense of the term; just use the "this" object, which stands for the current calling context, and which will be set to your Application object when calling the methods:
Application = {};
(function() {
Application.myFirstMethod = function() {
if (arguments.length) {
this.foo = arguments[0];
} else {
return this.foo;
}
};
Application.mySecondMethod = function() {
if (arguments.length) {
this.bar = arguments[0];
} else {
return this.bar;
}
};
})();
Application.myFirstMethod(3.14);
console.log(Application.myFirstMethod());
Application.mySecondMethod(2097);
console.log(Application.mySecondMethod());
console.log(Application.myFirstMethod());
Here's what I figured out. I probably need to use the word new somewhere though.
Application = {};
(function() {
Application.myFirstMethod = FirstMethod();
Application.mySecondMethod = SecondMethod();
function FirstMethod() {
var closure = {};
return function(myArgument) {
if (arguments.length) {
closure.result = arguments[0]; // myArgument
} else {
return closure.result;
}
}
}
function SecondMethod() {
var closure = {};
return function(myArgument) {
if (arguments.length) {
closure.result = arguments[0]; // myArgument
} else {
return closure.result;
}
}
}
})();
Application.myFirstMethod(3.14);
result = Application.myFirstMethod();
log(result);
Application.mySecondMethod(2013);
result = Application.mySecondMethod();
log(result);

Categories

Resources