var a = 2;
function f(a) {return a;}
console.log(f(1));// return 1
console.log(f());// return undefined, but I want to make it return 2...
f() returns undefined, but I want to it refer the variable a in global scope. How could I achieve that?
var a = 2;
function f(b) {
return b || a;
}
You need to use a different name for the function argument, else it's going to shadow the outer a and won't give you any chance to return it. Then it's a simple matter of deciding which value to return. Here I'm using a simple falsey check, you may or may not want to use something more detailed like typeof b === 'undefined' or such.
Use arguments.length to test if a parameter was passed to the function:
var a = 2;
function f(b) {
if(arguments.length===1) return b;
return a;
}
console.log(f(3)); //3
console.log(f(undefined)); //undefined
console.log(f(0)); //0
console.log(f()); //2
you could do something like this, which checks if the variable has been defined or not.
var a = 2;
function f(x) {
return (typeof x==="undefined")? a : x;
}
console.log(f(1));// return 1
console.log(f());// return 2
Related
function Square(a) {
this.a = a ** 2;
return a;
}
const value = Square.call({}, 5);
console.log(value.a);
Actual -> value.a = undefined
Expected -> value.a = 25
You are returning a, so 5, not the object. And you pass an object {} for this, but it is not stored anywhere, you can't check it later. If you passed an object which you have access to afterwards, like diz below, its .a becomes 25 properly:
function Square(a) {
this.a = a ** 2;
return a;
}
const diz = {};
const value = Square.call(diz, 5);
console.log("Returned 'a', should be 5:",value);
console.log("Altered 'object.a', should be 25:",diz.a);
Alternatively you might have wanted to return this;:
function Square(a) {
this.a = a ** 2;
return this;
}
const value = Square.call({}, 5);
console.log(value.a);
I don't know why you use this, or where this object value is coming from. But let me explain. Your argument a can't be changed directly. You need to assign it to a variable, e.g. result to change and return it.
return result = a ** 2;
To call the function, you don't use .call. You simply call it in your console.log().
console.log(square(a));
The whole magic of this function you want to write:
function square(a) {
return result = a * a;
}
console.log(square(a));
// expected result is 25
I recommend a course on freeCodeCamp to learn the fundamentals of JavaScript. You can find it here.
I have a function which has other functions defined:
var A = function(n) {
console.log(n + A.num());
}
A.num = function() {
return 5;
}
I want to change the name to B and delete A:
var B = A;
A = undefined;
But, when I do B(), It gives an error throws: "Cannot read property 'num' of undefined", which is completely normal and expected.
How do I handle this?
PS: Anyone who thinks that changing A.num() with this.num(), It will not work
You can always refer to the current function using its explicit name (if it has one).
So, change the definition, to name the function, and refer to it using that:
var A = function currentFunction(n) {
console.log(n + currentFunction.num());
}
A.num = function() {
return 5;
}
var B = A;
A = undefined;
B(10); //15
console.log(typeof currentFunction) //undefined, function name is local
Note: the abovementioned approach won't work if the function is named implicitly, but will continue to work if the function is renamed via fn.name
Alternatively, if the function isn't an arrow function, you can also use arguments.callee, that will work even with anonymous functions, but its use isn't recommended:
var A = function (n) {
console.log(n + arguments.callee.num());
}
A.num = function() {
return 5;
}
var B = A;
A = undefined;
B(10); //15
Unfortunately, none of the above will work with arrow functions, if you want to refer to itself, use a named bound function expression instead.
actually that's normal, because in js you can't really copy object
// Define object bar
var bar = {
x : 'Hi'
}
console.log(bar.x); //Hi
// Assign it to foo
var foo = bar;
console.log(foo.x); //Hi
//But
foo.x = 'Hello!! Im foo.';
console.log(foo.x); //Hello!! Im foo.
console.log(bar.x); //Hello!! Im foo.
bar.x = "Nice to meet you foo!!";
console.log(foo.x); //Nice to meet you foo!!
console.log(bar.x); //Nice to meet you foo!!
you have to return a new one with the same value as the last
var foo = {...bar};
and this is not working because B is always calling 'num' from A that doesn't exist, One way to sever the parity would be stringify the initial function, then use a function constructor to create the clone after replacing the 'A' by 'B'
but tell me more why are you facing this problem ?
var A = function(n) {
if(!this.num){
console.log("This is not available coz obj is not created");
console.log("Below error is for testing purpose");
}
let a=this.num(n);
console.log(a);
}
//use prototype here
//A.num = function() {
A.prototype.num=function(n){
return n+5;
}
//use new to create object
new A(5);
var B = A;
A = undefined;
//use new to create object
new B(6);
B(5);//lets try without using new keyword
.as-console-wrapper { max-height: 100% !important; top: 0; }
Suppose I'm testing a function and I want my function to display some information about itself ONLY IF a test doesn't pass.
I don't want to alter the flow of the function while saving data for latter use.
function foo(input){
//normal work of the function
//save the value of variable A
//normal work of the function
//save the value of variable B
//normal work of the function
}
This would be a test
fooTest(){
var condition = foo();
//display variable A and B depending on the value of the condition
}
How do I do it?
In my case, I'm testing functions and I want them to show me their value if their tests fails. If they don't fail I don't want to display information on the screen.
You might want to use a closure to preserve the value of variable after the function has been executed.
function set(A, B) {
// perform your operation
let a = A;
let b = B;
// The nested scope will remember the parent's scope
const getA = function() { return a; }
const getB = function() { return b; }
return { getA, getB };
}
var obj = set(10, 20);
console.log(obj.getA());
console.log(obj.getB());
this could be a good place do use .call() in order to alter this context:
function foo(input){
//normal work of the function
this.A = 10;
//normal work of the function
this.B = 20;
//normal work of the function
}
function fooTest() {
let obj = {};
let condition = foo.call(obj);
console.log(obj.A, obj.B);
}
fooTest()
Having seen a lot of pure functions and how they have no side effects, what would be an example of an impure function, which is always been antagonized as unstable and major source of error?
For example an impure function that has a side effect on a variable outside of its own scope:
var count = 0;
function increaseCount(val) {
count += val;
}
Or a function that returns different values for the same input because it evaluates a variable that is not given as parameter:
var count = 0;
function getSomething() {
return count > 0;
}
A pure function doesn’t depend on and doesn’t modify the states of variables out of its scope.
Concretely, that means a pure function always returns the same result given same parameters. Its execution doesn’t depend on the state of the system.
var values = { a: 1 };
function impureFunction ( items ) {
var b = 1;
items.a = items.a * b + 2;
return items.a;
}
var c = impureFunction( values );
// Now `values.a` is 3, the impure function modifies it.
Here we modify the attributes of the given object. Hence we modify the object which lies outside of the scope of our function: the function is impure.
var values = { a: 1 };
function pureFunction ( a ) {
var b = 1;
a = a * b + 2;
return a;
}
var c = pureFunction( values.a );
we simply modify the parameter which is in the scope of the function, nothing is modified outside!
var values = { a: 1 };
var b = 1;
function impureFunction ( a ) {
a = a * b + 2;
return a;
}
var c = impureFunction( values.a );
// Actually, the value of `c` will depend on the value of `b`.
// In a bigger codebase, you may forget about that, which may
// surprise you because the result can vary implicitly.
Here, b is not in the scope of the function. The result will depend on the context: surprises expected!
var values = { a: 1 };
var b = 1;
function pureFunction ( a, c ) {
a = a * c + 2;
return a;
}
var c = pureFunction( values.a, b );
// Here it's made clear that the value of `c` will depend on
// the value of `b`.
Reference : For more details, click here
Math.random() is an impure function; it changes the internal state of the Math object so you get different values on successive calls. console.log() and alert() are impure functions because they have side effects (although they generate the same behavior and always return the same value for identical calls).
Any function that changes the internal state of one of its arguments or the value of some external variable is an impure function. This includes closures where calling a method changes the internal state of the closure itself:
let nextInt = (function() {
var i = 0;
return function() {
return i++;
};
})();
let a = nextInt(); // sets a to 0
let b = nextInt(); // sets b to 1
// etc.
Where'd you get the idea that impure functions are always considered a bad thing?
Impure functon is a function which returns different result for
same input parameters, that is to say that it depends on some state;
Function that may return same result for same input parameters, but
that mutates other state object. object that it does not depends but others do // causes side effects
example:
1)
var toggled = false; /* state */
/*impure function*/
function impureFn(number){
if(number%2 == 0)
toggled = true;
return toggled;
}
/*Execute this in order */
impureFn(5) // returns false
impureFn(2) //returns true
impureFn(5) // now returns true
An example i can think of (that is indeed quite confusing) is Array#reverse(). Instead of returning a new array, it modifies it in place while returning the original array.
Some other array functions do this as well, such as splice, push, shift, pop, unshift.
pure function (get argument and return new value):
function (objectArgument) {
return {
value: objectArgument.value + 123,
// other arguments
};
}
impure function (get argument, modified it and return modified object):
function (objectArgument) {
objectArgument.value += 123;
return objectArgument;
}
I'm trying to make a function that can be applied to a value returned from another function both within a function. Since that's probably a terrible explanation, here's a simplified sample:
function MainFnc() {
this.subFnc=function(a) {
return a*2
}
this.subFnc.subSubFnc=function(a) {
return this*a
}
}
This isn't my actual code - it's for a far better reason than multiplying numbers. This is just a simplified example of what I'm trying to achieve. My question is whether or not it's actually possible to go this deep, and if so how? The method I've portrayed in this sample code evidently does not work.
Thanks for any help.
Edit: Here's an example of it in use since not everyone understands clearly what I want to do with this:
anObject=new MainFnc;
alert(anObject.subFnc(2)); //returns 4
alert(anObject.subFnc(2).subSubFnc(2); //returns 8
This is not exactly what I'm doing, it's just easier to understand using simple multiplication.
This is about as close as you can get:
function foo(n){
this.value = n;
return this;
};
foo.prototype = {
valueOf : function(){
return this.value;
},
multiplyBy : function(n){
return new foo(this.value * n);
}
};
foo.prototype.toString = foo.prototype.valueOf;
var x = new foo(2);
var y = x.multiplyBy(2).multiplyBy(2).multiplyBy(2);
// y == 16
Update based on your comment:
MainFnc is an object which is created in a variable (ie MainVar). So if I wanted to try MainVar.subFnc(2) it'd return 4. If I wanted to try MainVar.subFnc(2).subSubFnc(2), however, it'd return 8.
Right now, you're returning a number from your subFnc, and so the expression MainVar.subFnc(2).subSubFnc(2) breaks down like this:
Look up the property subFnc on MainVar; it returns a function reference.
Call the function with this = MainVar; this returns the number 2.
Look up the property subSubFnc on the number 2; it returns undefined.
Call the function with this = 2; fails because you can't call undefined as a function.
More: You must remember this and Mythical Methods
To do what you're doing, you'd have to have subFnc return an object with function properties. You could do it like this:
function MainFnc(val) {
this.value = val;
this.mult=function(a) {
return new MainFnc(this.value * a);
};
this.div=function(a) {
return new MainFnc(this.value / a);
};
this.get = function() {
return this.value;
};
}
...and then call it like this:
var MainVar = new MainFnc(3);
alert(MainVar.mult(3).mult(4).div(6).get()); // alerts "6" (3 * 3 * 4 / 6 = 6)
Live example
Note the get function to return the underlying number. You might also add a toString:
this.toString = function() {
return String(this.value);
};
But the above isn't taking advantage of prototypical inheritance at all (and it will be important to, if you're creating all of those objects; we need to keep them lightweight); you might consider:
function MainFnc(val) {
this.value = val;
}
MainFnc.prototype.mult = function(a) {
return new MainFnc(this.value * a);
};
MainFnc.prototype.div = function(a) {
return new MainFnc(this.value / a);
};
MainFnc.prototype.get = function() {
return this.value;
};
MainFnc.prototype.toString = function() {
return String(this.value);
};
Original Answer:
With that code, if you did this:
var f = new MainFnc();
alert(f.subFnc(3)); // alerts "6"
alert(f.subFnc.subSubFnc(3)); // NaN
...because this inside subSubFnc when called like that is subFnc, and multipling a function reference tries to convert it to a number, which comes out NaN, and so the result of the multiplication is NaN.
Remember that in JavaScript, this is defined entirely by how a function is called, not where the function is defined. When you call a function via dotted notation (a.b();), the object you're looking up the property on becomes this within the function call, and so with a.b.c();, this within c() is b, not a. More: You must remember this and Mythical Methods