Nodejs console overload scope issue - javascript

I am trying to override the console in Nodejs with Winston.
for (var z in loggerSettings) {
console[z] = (function () {
var i = z + ''
, _backup = console[z];
return function () {
var utfs = arguments.length >= 2 ? util.format.apply(util, arguments) : arguments[0]
, coldex = 0;
if (true) logger[i == 'log' ? 'info' : i](utfs);
if (loggerSettings[i].console){
if ((coldex = utfs.indexOf(']') + 1) <= MAX_TAG_LENGTH)
_backup(utfs.substring(0, coldex)[i]['inverse'] + utfs.substring(coldex));
else _backup(utfs);
}
}
})();
}
Here var z is just a the basic console.log, console.info, console.warn methods. The issue is z is changing for each of the anonymous function. It is a bit challenging to address the problem, but the scope of z seems to change and the variable z is not exactly sticking to a constant value for each iteration of the loop. Z doesn't want to stick to its scope.

Javascript has function scope, but no block scope, meaning that every reference to z in your console-functions will use the last value of z.
If you want 'z' to stick, pass it as an argument to an anonymous function:
for (var z in loggerSettings) {
(function(z) {
console[z] = (function () {...});
)(z);
};

Related

JS Closures - What is the value of x?

This is a thought exercise. I'm not doing anything with this code and the purpose is to better understand how closures work.
Thought Process:
x === 10 in global scope.
outer() function is called.
x === 20 in the global scope and local scope.
inner() function is called.
right side of 'var x' is expressed.
In x + 20, because x is not defined in local scope, it searches outer scope and finds x === 20.
var x = 20 + 20.
var x === 40.
return x.
result === 40.
However, the answer is 20. Why is this?
var x = 10;
function outer () {
x = 20;
function inner () {
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;
When the inner() function is called, the first thing that happens is var x.
This means the JavaScript interpreter first creates a variable named x to which it assigns undefined.
Then it runs the assignment expression x + 20, which is equivalent to undefined + 20 which is NaN.
Your variable result has nothing to do with your inner() function as you have a local variable (because of that var x) and you ignore the returned result.
In other words, your code is equivalent to just this:
var x = 10;
function outer () {
x = 20;
}
outer();
var result = x;
Because your inner function defined a local var x which will hide the global variable outside. And the outer function uses the global variable x and assign it to 20. Obviously, the global x is 20. Javascript will define every local variable before you call the function in the prototype chain.
var x = 10;
function outer () {
x = 20;
function inner () {
alert(x); // alert undefined
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;

js variable value in a function from which scope [duplicate]

This question already has answers here:
Javascript scoping of variables
(3 answers)
Closed 6 years ago.
i have this code in java script
var x = 5;
function f(y) { return (x + y) - 2 };
function g(h) { var x = 7; return h(x) };
{ var x = 10; z = g(f) };
z value is 15. why?
the expression (x+y)-2 is being evaluated as (10+7)-2.
why does x get the value of 10, and not the value of the previous
block, where x = 7?
thanks for the help
You can completely delete the first assignment. It gets overwritten before you call g(f).
Also, you can remove the parentheses of the last block as there is no block scope in JS (actually block scope got introduced with let, so you wanna use that instead).
var x = 5;
function f(y) {
// global variable x is 10 -> 10 + 7 - 2 = 15
return (x + y) - 2;
}
function g(h) {
// x gets declared locally - local value will be used
var x = 7;
return h(x); // f gets called with y = 7
}
x = 10; //global x gets changed
z = g(f);
... and always place your semicolons. Even though they maybe look optional but in some cases they are obligatory.
Value of variable x is 10 at global execution context.
When function f is finally called the value of the argument which is y, this y actually represent value of x at local execution context of function g, here x is 7.
var x = 5;
function f(y) {
return (x + y) - 2 ;
}; // value of global var x is 10, value of parameter passed is 7
// this value comes from the local var x of g function's execution context.
function g(h) {
var x = 7; return h(x); };
{ var x = 10; z = g(f); };
console.log(z);

Function in "natural language"

I've made a function "ADD" which modifies the value of a variable :
function ADD(xs, n)
{
var nom_variable = xs;
var XS = eval(xs);
nouvelle_valeur = eval(nom_variable + "=XS+n");
}
var x = 5 ;
ADD("x",5); // now x = 10
I would like that the first argument of the function ADD is x, not "x". Is this possible ?
I want my students to write algorithms in a way similar to natural language.
Thanks !
You can't pass x as if it were a reference, but you could construct a functional reference (or Lens) although you are still not passing x but a variable that is a reference of x.
var x = 5;
var xRef = {
get : function(){
return x;
},
set : function(val){
x = val;
}
}
function add(ref, n){
var oldVal = ref.get();
ref.set(oldVal+n);
}
add(xRef, 5);
console.log(x);
It's definitely not pretty though.

Why is a global variable (inside function) not identified?

So, I was trying to initialize variables and put a few global variables in my Unity script, but when I run the code, it says that x, y, and z are unknown identifiers. I've been trying to find the answer to this:
function Awake () {
x = 0; //Unity doesn't work with commas
y = 0;
z = 0;
}
function Update () {
if (Input.GetTouch) {
x = x-1;
}
Transform.position = Vector3(x,y,z);
}
The thing with putting the variables outside the function is that they will repeat and act as update.
I'm also new to Unity, and JavaScript.
It looks to me (granted with my limited exposure to unity) like you need to declare your variables at a global level. Try doing something like this:
// declare these variables in the global scope.
var x;
var y;
var z;
function Awake () {
x = 0;
y = 0;
z = 0;
}
function Update () {
if (Input.GetTouch) {
x = x-1;
}
Transform.position = Vector3(x,y,z);
}

What does the comma mean in the construct (x = x || y,z)?

So I've come across to an answer but it is not enough to expand my knowledge base.
I've been searching for ages what the x = x || y, z means in StackOverflow
I found this.
What does the construct x = x || y mean?
But the problem is what is the , z for?
I'm seeing these expressions quite often
window.something = window.something || {}, jQuery
I already know that if false was returned on the first argument then {} will be assigned to the something property.
My question is, What is the , jQuery for?
Can someone enlighten me and shower me with this very important knowledge?
UPDATE 8/11/2014
So I tried making tests.
var w = 0, x = 1,y = 2,z = 3;
var foo = w || x || y, z; //I see that z is a declared variable
console.log(foo); //outputs 1
and it is the same as this.
var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
var foo = w || x || y, z; //same as this
console.log(foo); //still outputs 1
another.
var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
function foobar(){
this.bar = console.log(foo,z);
}(foo = w || x || y, z);
foobar(); //outputs 1 and string code of foobar
changing the value of z in (foo = w || x || y, z).
var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
function foobar(){
this.bar = console.log(foo,z);
}(foo = w || x || y, z=4);
foobar(); //outputs 1 and 4
I assume that placing variables inside ( ) after the } of the function is the same as declaring a new variable.
Another test.
var w = 0, x = 1,y = 2,z = 1;
function foobar(){
var bar = 10,z=2;
console.log(z);
}(foo = w || x || y, z=4);
console.log(foo,z); // Seems that foo is public and made an output
foobar(); // outputs the z = 2 inside and disregards the z = 4 from (..., z=4)
console.log(z); // It seems that z is 4 again after calling foobar
However, in a scenario like this. Link to JSFiddle
//Self-Executing Anonymous Function: Part 2 (Public & Private)
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
//Public Properties
console.log( skillet.ingredient ); //Bacon Strips
//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips
//Adding a Public Property
skillet.quantity = "12";
console.log( skillet.quantity ); //12
//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
try {
//12 Bacon Strips & 1 Cup of Grease
skillet.toString(); //Throws Exception
} catch( e ) {
console.log( e.message ); //isHot is not defined
}
It seems that if you remove the , jQuery it only logs "Bacon Strips"
Refer to this link Link to another JSFiddle (, jQuery is removed)
I don't really get this.. But why is the , jQuery inside the ( ) after the } of a function counts as a reference for the code to run completely when the library of jQuery is already included?
Having the $.trim removed from the code, it seems to work fine again. But I still don't get how this referencing works.
Link to the JSFiddle without the , jQuery and $.trim
The Comma Operator in JavaScript evaluates operands and returns the value of the last one (right-most). By JS Operator Precedence, the OR operation will be evaluated first, followed by the assignment.
So this expression x = x || y, z is in effect (x = (x || y)), z. The OR operator will either return the boolean result of the comparison or, for non-boolean types, the first operand if it is truthy, or the second operand otherwise. The assignment operator is also higher precedence than the comma operator, so x will be assigned the value returned by the OR. The value of z will not have any effect on either the OR operation or the assignment. In fact, it will be evaluated last, meaning it is essentially a separate statement with no effect on anything else in that 'expression.' I can't see any practical value in writing the expression that way.

Categories

Resources