I have a function freq01(), when a button is clicked I want a function(new) to create a copy of function freq01(), with new parameters. I have no idea where to start or if JS can create a function from a function.
All variables have been created. Please point me in the right direction...!
The code below is to save the checked radio button value to an array.
function freq01(){
if (document.getElementById("w01").checked){
incFreq = document.getElementById("w01").value;
}
else if (document.getElementById("f01").checked){
incFreq = document.getElementById("f01").value;
}
else if (document.getElementById("m01").checked){
incFreq = document.getElementById("m01").value;
}
}
I have no idea ... if JS can create a function from a function.
To answer this part of your question, yes Javascript can create a function from a function. Any function can return another function, and the typical ways to do this would be to create a factory function, or use function currying to create new functions:
Factory
A function that returns another function. Due to Javascript closures, you can set "private" variables that the returned function can see, but the calling function cannot access:
function addTwoFactory() {
let a = 2;
return function(b) {
return a + b;
}
}
let f1 = addTwoFactory();
let f2 = addTwoFactory();
console.log(f1(3)); // 5
console.log(f2(3)); // 5
Can also make configurable factories that can create different sorts of methods:
function makeAdder(a) {
return function(b) {
return a + b;
}
}
let addTwo = adderFactory(2);
let addThree = adderFactory(3);
console.log(addTwo(3)); // 5
console.log(addThree(3)); // 6
Currying
Function currying is the idea of taking a base function that takes several parameters, and "baking in" one of the parameters, to reuse more easily:
function adder(a, b) {
return a + b;
}
function makeAdder(a) {
return function(b) {
return adder(a, b);
}
}
let addTwo = makeAdder(2);
console.log(addTwo(3)); // 5
You can try to use bind https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
var freq01 = freqBase.bind(null, "w01","f01","m01");
function createNewFunc(i){
return freqBase.bind(null, "w0"+i,"f0"+i,"m0"+i);
}
function freqBase(a,b,c){
if (document.getElementById(a).checked){
incFreq = document.getElementById(a).value;
}
else if (document.getElementById(b).checked){
incFreq = document.getElementById(b).value;
}
else if (document.getElementById(c).checked){
incFreq = document.getElementById(c).value;
}
}
var func2 = createNewFunc(2);
var func3 = createNewFunc(3);
func2();
func2();
func2();
func3();
func2();
Other idea is to just return new function
var newf1 = function createNewFunc(i){
return function(){ return i;}
}
newf1(1)();
newf1(1)();
newf1(1)();
shorter version could be:
a = (i)=> ()=> { return i; }
or more readable
const f2=function createNew(i){
return ()=> { return i; }
};
const res = f2(1)();
Related
I am about to rewrite an app (it is in vanilla JS originally) in ES6, in which module patter is apllied.
In no time, at the beginning I realized that I am struggling to get 'separation of concerns' done since if we are about to apply data privacy in ES6 we only use "{}" but not IIFE's as in case of vanilla JS (which as known are practically function expressions).
Vanilla JS solution:
var budgetController = (function() {
const x = 20;
function add(a) {
return x + a;
}
return {
getSum: function(b){
console.log(add(b));
}
}
})();
UIController = (function() {
// some code
})();
Controller = (function(BudgetCrtl, UICtrl) {
var n = BudgetCrtl.getSum(3);
console.log(n);
})(budgetController, UIController);
In ES6 I attemted to use simply func expressions not IIFE's in order to pass the other modul in the controller modul and be able to use/pass over the public methods but it dod not work.
ES6 attempt:
let budgetController = function() {
const x = 20;
function add(a) {
return x + a;
}
return {
getSum: (b) => console.log(add(b))
}
}
UIController = function() {
// some code
}
Controller = function(BudgetCrtl, UICtrl) {
const n = BudgetCrtl.getSum();
console.log(n);
}
Controller(budgetController, UIController);
Could anyone provide me with some solution to involve somehow in ES6 the so called encapsulation and above mentioned things? Any idea would be appreciated!
Cheers, thank you!
You need to execute that BudgetCrtl to get access to the getSum function like so BudgetCrtl().getSum(3), since that BudgetCrtl is a function and not
a value returned from it's execution .
plus if you want the value to be stored to the n you should not console.log in the arrow function immediately, because the way it is now it's implicitly returning undefined
let budgetController = function() {
const x = 20;
function add(a) {
return x + a;
}
return {
getSum: (b) => {
let newVal = add(b)
console.log(newVal)
return newVal // so that you can store the value in `n`
}
}
}
UIController = function() {
// some code
}
Controller = function(BudgetCrtl, UICtrl) {
const n = BudgetCrtl().getSum(3);
console.log(n);
}
Controller(budgetController, UIController);
I am trying to build two functions to work like jQuery functions work, for example: jQuery( 'select').val();
This works:
function func(a) {
console.log(1);
return a;
}
func.sub = function(n) {
console.log(2);
}
func.sub(2);
But this doesn't:
function func(a) {
console.log(1);
return a;
}
func.sub = function(n) {
console.log(2);
//return func result[n];
}
func([1,2,3]).sub(2);
How can I make this second code work and read func() result on sub()?
You need to have func return an object that has a method sub.
function Subbable(x) {
this.value = x;
}
Subbable.prototype.sub = function(b) {
return this.value - b;
}
function func(a) {
return new Subbable(a);
}
func(10).sub(2)
// 8
jQuery's $(...) typically returns a jQuery object that contains a collection of the selected nodes, and whose prototype has all the nice goodies like .attr and .css.
I have this spec from Jasmine.js which tests a once function. I'm not sure how to implement such a function though.
/* Functions that decorate other functions. These functions return a version of the function
with some changed behavior. */
// Given a function, return a new function will only run once, no matter how many times it's called
describe("once", function() {
it("should only increment num one time", function() {
var num = 0;
var increment = once(function() {
num++;
});
increment();
increment();
expect(num).toEqual(1);
});
});
I don't quite understand what should I do here. I know I should make a function once(myFunction) {} but other than that, I am stuck. I figure out this has something to do with closures, still can't my head around it.
If you prefer not to use UnderscoreJS, you can implement a simpler "once" function yourself like this:
var once = function (func) {
var result;
return function () {
if (func) {
result = func.apply(this, arguments);
func = null;
}
return result;
}
};
When you pass your function as the argument to this once function (as the parameter as 'func'), it returns a function that can only be called once.
It accomplishes this feat, in short, by creating a results variable and assigning that variable the results of calling your function with its supplied arguments--but only the first time it is run. Otherwise, when the function is invoked subsequent times, it will never enter your if statement (because the func variable was set to null in the first invocation) and the value referenced by the results variable (set during the first invocation and accessed via closure) will be returned.
Copied from the UnderscoreJS source:
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
http://underscorejs.org/docs/underscore.html
Very, very minimal
const once = fn => (...args) => {
if (!fn) return;
fn(...args);
fn = null;
};
(Old school version)
function once(fn) {
return function() {
if (!fn) return;
fn.apply(null, arguments);
fn = null;
}
}
I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()
What is the best way to deal with the following situation in JavaScript.
I have three methods (m1, m2, m3) and the last one (m3) depends from the results of the others two (m1, m2).
In this way it works, but I am curious to know if there is a better way to write the code in this situation, especially for future developers that will read the code.
var O = function () {
this.p = 0;
}
O.prototype.makesomething = function () {
var that = this;
that.m1();
that.m2();
that.m3();
}
O.prototype.m1 = function () {O.p++}; // it changes the value O.p
O.prototype.m2 = function () {O.p++}; // it changes the value O.p
O.prototype.m3 = function () {return O.p}; // m3 depends by m1, m2 because it needs to get the update value of O.p
First, I don't know for sure, but putting this.p = 0 inside O does not make sense in combination with O.p. You probably mean this.p inside m3, when referring to the instance.
Anyway, if you are looking for readability, you could make some simple but idiomatic functions like this: http://jsfiddle.net/ZvprZ/1/.
var O = function () {
this.p = 0;
}
O.prototype.makesomething = function () {
var that = this;
var result = when( that.m1(), that.m2() )
.then( that.m3() );
return result;
}
O.prototype.m1 = function () {this.p++};
O.prototype.m2 = function () {this.p++};
O.prototype.m3 = function () {return this.p};
The when/then can be rather straight-forward since it does not do anything than making it more readable:
(function(window) {
var when, then, o;
when = function() {
return o; // just return the object so that you can chain with .then,
// the functions have been executed already before executing
// .when
};
then = function(a) {
return a; // return the result of the first function, which has been
// executed already (the result is passed)
};
o = { when: when,
then: then };
window.when = when; // expose
window.then = then;
})(window);