Is it possible to /manipulate/ functions as it is strings? - javascript

var myString = '';
myString += 'foo';
myString += 'bar';
myString = myString.replace(/oba/, 'qux');
console.log(myString) // produces "foquxr"
Is there any way to likewise tinker around with functions, like, say, turning function(a) { a += 'b'; return a; } info function(a) { a += 'b'; console.log(a); return a + 'c'; }?

You can compose functions thus
// (compose(f, g))(x, y, ...) is the same as f(g(x, y, ...))
function compose(f, g) {
return function (var_args) {
return f.call(this, g.apply(this, arguments));
};
}
so
var f = compose(
function (x) { console.log(x); return x + 'c'; },
function (a) { a += 'b'; return a; });
lets you combine two small functions to get a function that behaves like
function(a) { a += 'b'; console.log(a); return a + 'c'; }

You could achieve this (without using eval) by getting the function's body from its declaration, manipulating it as needed, and redefining it by means of the Function() constructor:
function myFunction(a) { a += 'b'; return a; }
function changeFunction(){
var func = window['myFunction'].toString();
var body = func.substring(func.indexOf("{")+1, func.lastIndexOf("}"));
body = body.replace("return a;", "console.log(a); return a + 'c';");
window.myFunction = Function("a", body);
}​
Here's a JSFiddle

Related

How to access grand-child's variable in a closure

I want to retrieve the values of a and b from p in the code given below. I would also like to run the function z from p. How do I achieve this?
function x() {
var a = 10;
return function y() {
var b = 20;
return function z() {
console.log(a, b);
}
}
}
const p = x();
I'm new to JS.
function x() {
var a = 10;
return function y() {
var b = 20;
return function z() {
console.log(a,b)
}
}
}
// get function z
const result = x()();
console.log(result)
// get a,b
result()
Calling x returns function y, calling y returns function z i.e. x()();
By calling function z, you can get a,b (return or console) i.e. x()()();

Function that gets it's properties

How can I create a function where it gets it's property?
For example:
myfunc = function(){
alert(this.a + ":" + this.b);
};
myfunc.a = 5;
myfunc.b = 6;
The results is 5:6
There are two ways. The first, is as others have mentioned is to name the parameters in your function delcaration:
function foo(a, b) {
alert(a + ':' + b);
}
foo('hello', 'world'); // Output "hello:world"
Another way however is that a variable is available which contains all function parameters, called arguments.
function bar() {
alert(arguments[0] + ':' + arguments[1]);
}
bar('hello', 'world'); // Output "hello:world"
It should be noted that while it looks like an array, the arguments variable is not an instance of the JavaScript Array object, the only Array property available to use with arguments is .length.
This could be done with a closure:
var myFunc = (function(a, b) {
return function() {
console.log(a + ":" + b);
}
})(5, 6)
myFunc();
This can be expanded via prototype to create class like behaviour:
var myFunc = (function () {
function myFunc(a, b) {
if (a === void 0) { a = 5; }
if (b === void 0) { b = 6; }
this.a = a;
this.b = b;
}
myFunc.prototype.log = function () {
console.log(this.a + ":" + this.b);
};
return myFunc;
}());
var a = new myFunc();
a.log();
new myFunc().log();
new myFunc(1, 10).log();
//ACCESS ATTRIBUTE
console.log("ACCESSING", a.a);
//OVERWRITE ATTRIBUTE
a.a = 11;
//ACCESS ATTRIBUTE
console.log("ACCESSING", a.a);
a.log();
Try this:
myfunc = function(){
alert(this.a + ":" + this.b);
};
myfunc.call({a: 5, b: 6});
When you use the call function, the first parameter is your function's this and the second parameter is your function. The call function just call you function and assign {a: 5, b: 6} to myfunc's this.

Defining getters and setters after the object is instantiated

This bit of code comes from MDN:
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2
}
};
$('body').append(o.a + '<br>')
$('body').append(o.b + '<br>')
o.c = 50;
$('body').append(o.a + '<br>')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
What I would like to do is break it down even further. I've gotten as far as line 3 like so:
var o = {}
o.a = 7
o.get b() { // broken
Is there a way that I can break the getters and setters out so that it's not one long definition inside the o = {}?
Object.defineProperty is what you're looking for:
var o = {};
Object.defineProperty(o, 'a', {
get: function() { return 1; },
set: function(val) { console.log(val) }
});
You can achieve this using Object.defineProperty():
Object.defineProperty(o, "b", {
get: function() {
// return something
}
})
See demo below:
var o = {};
o.a = 1;
Object.defineProperty(o, "b", {
get: function() {
return this.a + 1;
}
});
console.log(o.b)

Get return value of first function invocation match without invoking it twice

I have an array of function references.
I need to find the return value of the first function invocation that satisfies my match condition.
How can I avoid calling the matched function twice?
var f = function(x) { if (x === 10) return "ten"; }
var g = function(y) { if (y === 20) return "twenty"; }
var result = [f, g].find(m => m(10))
if (result) return result(10)
// this returns "ten"
Still not sure I fully understand you question. It seems to me that you want to iterate through an array of functions and return the result if the function called with the condition is truthy.
let fncaller = (fns, condition) => {
var result
for (var fn of fns) {
result = fn(condition)
if (result) { return result }
}
}
Can you use global variables?
var f = function(x) {
return x % 2 == 0
}
var g = function(y) {
return x % 2 == 1
}
var result = [f, g].find(function(m) {
window.blah = m(10);
return window.blah;
})
console.log(window.blah);
Or #DaveNewton's method. Not sure which is faster:
var f = function(x) {
if (x === 10) return "ten";
}
var g = function(y) {
if (y === 20) return "twenty";
}
var funcs = [f, g];
function checkIt(value) {
for (var i = 0, numFuncs = funcs.length; i < numFuncs; ++i) {
var v = funcs[i](value);
if (v) return v;
}
}
console.log(checkIt(20));
You could store in a variable as you go. It's better than using a global.
var f = function(x) { if (x === 10) return "ten"; };
var g = function(y) { if (y === 20) return "twenty"; };
function findValue(funcs, val) {
var result;
funcs.find(m => result = m(val));
return result;
}
console.log(findValue([f, g], 10));

Javascript Object or new function for function handler

I am a bit confused as which one of the following is the right way to create a handler containing functions...An object with function or a new function itself?
Say, a handler for calculator functions...
CalculatorHandler = new function(){
this.add = new function(a, b){
return a + b;
};
this.sub = new function(a, b){
return a-b;
};
};
Or
CalculatorHandler = {
this.add: function(a, b){
return a + b;
},
this.sub: function(a, b){
return a-b;
}
};
Are there any advantage/disadvantage of one over the other?
If you just want to have a "basket" to hold your functions together, simply use an object, there is no need for a constructor function:
CalculatorHandler = {
add: function(a, b){
return a + b;
},
sub: function(a, b){
return a-b;
}
};
Note how the this in your example is incorrect as it will refer to the scope you define the CalculatorHandler object in (probably global - window).
On the other hand if you want to build a calculator to have some data and do operations on it, then you can use the OOP-like approach in your first example.
CalculatorHandler = function() {
this.total=0;
this.add = function(a) {
this.total += a;
};
this.sub = function(a) {
this.total -= a;
};
}
var calc = new CalculatorHandler();
calc.add(4);
calc.sub(3);
And a better solution, based on prototipal inheritance:
CalculatorHandler = function() {
this.total=0;
}
CalculatorHandler.prototype.add = function(num) {
this.total += num;
}
CalculatorHandler.prototype.sub = function(num) {
this.total -= num;
};
var calc = new CalculatorHandler();
calc.add(4);
calc.sub(3);

Categories

Resources