Same function name in javascript (Nested function and outside function ) [duplicate] - javascript

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 5 years ago.
I have a function as below.
My Problem is that I need to print function b() inside a function. Here function a() is parent function. and I have done it by taking c= new a() and console.log(b()) . I got the right value as I expected. But inside the parent function I have another function named test() and with same name there is another function outside the parent function. After printing function b() I call the function test() . But it return the value from the parent function. I need to get an alert as needed answer which is in outer function. Is there any way to get my expected result without changing the function name.? Both functions test() are needed.
Expected result: function b() = 2 and function test() = needed answer
Current result : function b() = 2 and function test() = 4
Any help will be appreciated. Thank You.
function a() {
var val = 1;
var otherval = 2;
b = function() {
return val + 1;
}
test = function() {
qwerty = otherval + b();
alert(qwerty);
}
return 'OK';
}
function test(){
alert('needed answer');
}
c = new a();
console.log(b()); //return 2
test(); //alert 4 but I needed alert needed answer

As Rajesh Pointed out, declaring a function without using var will make it a global variable. Use var before test function to get expected value. But this will make it inaccessible outside the function a(). For that, assign the functions to this object and access then as shown below.
function a() {
var val = 1;
var otherval = 2;
this.b = function() { //prepend this
return val + 1;
}
this.test = function() { //prepend this
qwerty = otherval + b();
alert(qwerty);
}
return 'OK';
}
function test(){
alert('needed answer');
}
c = new a();
console.log(c.b()); //return 2
test(); //alert 4

You need slight modification in your code. Do this and it will work as per your requirement -
function a() {
var val = 1;
var otherval = 2;
b = function() {
return val + 1;
}
this.test = function() {
qwerty = otherval + b();
alert(qwerty);
}
return 'OK';
}
function test(){
alert('needed answer');
}
c = new a();
alert(this.b()); //return 2
test(); //alert 4

Related

Why can't I declare functions or variables at the block statement? [duplicate]

console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
====================
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a) // this code throws Uncaught SyntaxError: Identifier 'a' has already been declared
both above code snippets are same except the if block.why does the latter throws error when its permissible in javascript to delcare same variable twice in the same scope with var as below
function a(){};
var a = 10; //no error
Also for a slightly different scenario after removing var from `var a = 10 in the above code ,then it works fine but output is surprising
var a = 1;
if(true) {
function a(){};
a = 10;
}
console.log(a) //output:ƒ a(){}
I am surprised to see this output as I am expecting 10 ..because two variables declared inside the if block refer to the same variable declared above as javascript var doesnt respect block scope but functional scope...so why not the output for above should be 10?
where as the below code outputs 10 as i expected when replaced the function definition with function expression.
var a = 1;
if(true) {
var a = function(){ console.log() }
a = 10;
}
console.log(a) //output:10
This is surprising as javascript var doesn't respect block scope but functional scope...
Sure, but you didn't use var for the declaration of a in the block scope. You used a function declaration, which does respect block scopes (otherwise it would be completely invalid code, as in ES5 strict mode).
It's permissible in javascript to declare same variable twice in the same scope with var as below
Same applies here. The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow redeclarations.
Case 1
console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
Will be rendered as
var a;
a = function(){}; // now a holds the value as a function
console.log(a); // output : f a(){}
a = 1; // a is a var that holds value 1
a = 10; // a is a var that holds value 10
console.log(a); // output : 10
Case 2
var a = 1;
if(true){
function a(){};
var a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function() {};
let a; // The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow re-declarations.
var a; // throws Uncaught SyntaxError: Identifier 'a' has already been declared
a = 10;
}
console.log(a);
Case 3
var a = 1;
if(true){
function a(){};
a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function() {};
let a;
a = 10;
}
console.log(a); // output : f a(){}
Case 4
var a = 1;
if(true){
var a= function(){console.log()}
a = 10;
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true) {
a = function(){console.log()}
a = 10;
}
console.log(a) // output:10
Case 5
var a = 1;
if(true){
function a(){};
a = 10;
console.log(a)
}
console.log(a)
Will be rendered as
var a;
a = 1;
if(true){
a = function() {};
let a;
a = 10;
console.log(a); // output:10
}
console.log(a); // output : f a(){}
The simple solution to this is to use IIFE
(function() {
var sahil = {
checkThis: function() {
console.log(this);
function checkOther() {
console.log(this);
}
checkOther(); // checkThis() function called in "global context", will
// return "this" as "window"
}
};
var moo = sahil.checkThis;
moo(); // moo() function called in "global context", will return "this" as "window" })();

Closures: Scope Chain Variables - Not sure how variables link up

Really new to Javascript. This code is taken from MDN.
// global scope
var e = 10;
function sum(a){
return function sum2(b){
return function sum3(c){
// outer functions scope
return function sum4(d){
// local scope
return a + b + c + d + e;
}
}
}
}
var s = sum(1);
var s1 = s(2);
var s2 = s1(3);
var s3 = s2(4);
console.log(s3) //log 20
When I try to input different variable names (EX below) they don't seem to work and I don't understand how everything links up together to spit out the answer 20.
// global scope
var e = 10;
function sum(a){
return function sum2(b){
return function sum3(c){
// outer functions scope
return function sum4(d){
// local scope
return a + b + c + d + e;
}
}
}
}
var w = sum(1);
var x = s(2);
var y = s1(3);
var z = s2(4);
console.log(s3) //log 20
When I change it to this it also does not work. The console tells me that sa is not defined
// global scope
var e = 10;
function sm(a){
return function sa(b){
return function sb(c){
// outer functions scope
return function sc(d){
// local scope
return a + b + c + d + e;
}
}
}
}
var s = sm(1);
var s1 = sa(2);
var s2 = sb(3);
var s3 = sc(4);
console.log(sc) //log 20
I can keep throwing out more examples that don't work. Someone, please help me understand how the first example works.
function sm(a){
return function sa(b){
return function sb(c){
// outer functions scope
return function sc(d){
// local scope
return a + b + c + d + e;
}
}
}
}
The function sm is taking one argument and is returning a function which takes one argument. The function sm returns is not named sb. Try to think of it as the return value of sm .
So, when you do
var s = sm(1);
The returned function is stored in the variable s
Now if you want to run the second function (sa inside sm) you need to invoke s.
var s1 = s(2);
The returned function (sb) is stored inside varibale s1.
Similarly,
var s2 = s1(3);
var s3 = s2(4);
console.log(s3); // 20

JavaScript Closure - trying to understand following code

Coming from Java background trying to make sense out of the following code.
From:
https://medium.freecodecamp.com/lets-learn-javascript-closures-66feb44f6a44#.cbk6c4e9g
For function bar(c), which line passes argument c into bar(c) as I don't see it here.
Thanks.
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5); // Closure
/*
The function below executes the function bar which was returned
when we executed the function foo in the line above. The function bar
invokes boop, at which point bar gets suspended and boop gets push
onto the top of the call stack (see the screenshot below)
*/
moar(15);
When your first statement of function call var moar = foo(5) is executed
moar variable will be function bar(c){var d=30;return boop(x+a+b+c+d);
check the snippet for understanding
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
return bar;
}
var moor=foo(10);
console.log(moor);
2.After this statement moar(15),your are actually passing 15 to the bar method
It will execute bar method with c as 15. Now this function would return boop(80) which would just be -80
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5)
console.log(moar(15));
Hope it helps
moar(15) passes 15 into bar which gets copied into parameter c.
The // Closure comment is misleading because it is more useful to think of the closure being configured at the point of declaration of a function.
The reality is that the pointer to the outer lexical environment is configured when a function object is instantiated, and then this pointer is then copied to the execution context associated with any invocations of said function object.

Object function scope

factory(n) returns objects with functions.
func1 function definition creates its own scope, and x inside this function references x = n + ''.
But func2 is a reference and the scope is wrong.
Is there a way to return an object from create so its functions were references (not separate definitions)?
Actually, I'm fine with func1 approach while function definition footprint is small. If it is a complex function it would be better not to clone this function into every object comming from factory(n). inner_func may not use this, it is simple function. Also I want to avoid new and this.
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
return {
func1: function(y){return inner_func(x, y); },
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
var f1 = factory(2);
var f2 = factory(3);
var f1_func1 = f1.func1(4);
var f2_func1 = f2.func1(5);
var f1_func2 = f1.func2(4);
var f2_func2 = f2.func2(5);
console.log(f1_func1, f2_func1); //24 35
console.log(f1_func2, f2_func2); //!4 !5
You could define that function separately from the object initializer on the return statement:
var factory = (function(){
var x = '!';
return function create(n){
var x = n + '';
function func1(y) {
return inner_func(x, y);
}
return {
func1: func1,
/* vs */
func2: inner_func_api
}
}
function inner_func_api(y){ return inner_func(x, y); }
function inner_func(a, b){ return a + b; }
}());
However, it makes no practical difference, and it doesn't matter how big or complicated that function is. Function instances do take up space, but the code for the function is constant (immutable) and doesn't need to be part of every Function object created from the same piece of source code.

Can I pass parameter like reference

I need function change to change variables and return back to Tst1. I expect to get in console:
5
aaa
but have unchanged ones:
6
bbb
My functions:
function change ( aa,bb )
{
aa=5;
bb="aaa";
}
function Tst1()
{
aa=6;
bb="bbb";
change(aa,bb);
console.log (aa);
console.log (bb);
}
One way is to move change() into the function test(). Then it shares the same variables as the calling scope.
'use strict';
function test() {
function change() {
aa = 6;
bb = 76;
}
var aa = 5,
bb = 6;
change();
document.write(aa + " " + bb);
}
test();
JavaScript is like java in that primitives are never passed by reference but objects are always passed by reference. You need to wrap your data in an object and pass that instead:
function change (aa, bb)
{
aa.value = 5;
bb.value = "aaa";
}
function Tst1()
{
aa = { value: 6 };
bb = { value: "bbb" };
change(aa, bb);
console.log (aa.value); // outputs 5
console.log (bb.value); // outputs aaa
}
or you can play with global variable, but it is not a good practice.
var aa,bb;
function change(){
aa=6;
bb=76;
}
function test(){
aa = 5;
bb = 6;
change();
console.log(aa + " " + bb);
}
test();
Short answer: NO, you can't pass primitive parameters by reference in JS.
One alternative solution to the presented here is to return the result values as array of items:
function change ( aa,bb )
{
aa=5;
bb="aaa";
return [aa, bb];
}
function Tst1()
{
aa=6;
bb="bbb";
result = change(aa,bb);
aa = result[0];
bb = result[1];
document.writeln(aa);
document.writeln(bb);
}
Tst1();

Categories