What I mean is does node.js have object that are global function methods of. Like this in browser:
function myGlobalFunction() {
console.log(this === window);
}
myGlobalFunction();
=> true
The closest equivalent in node is global. I'm not sure if it translates in all of the same ways, but if you open a REPL and type in this === global, it will return true.
Here's a discussion on the global object, though some it the information may be deprecated as it's pretty old: 'Global' object in node.js
Yes, the global variable is the global object in Node.js
From the docs:
global# {Object} The global namespace object. In browsers, the
top-level scope is the global scope. That means that in browsers if
you're in the global scope var something will define a global
variable. In Node this is different. The top-level scope is not the
global scope; var something inside a Node module will be local to that
module.
Related
var myVariable = 3;
console.log('global', globalThis.myVariable);
I tried running the code using node file.js, but keep getting the result:
global undefined
Can someone explain to me what exactly is going on here?
I find this from Node documentation:
In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.
and Global object:
In JavaScript, there's always a global object defined. In a web browser, when scripts create global variables defined with the var keyword, they're created as members of the global object. (In Node.js this is not the case.)
It mean that when you declare var myVariable = 3; it doesn't go into the node global object, you can try to print global object out.
Try to assign value to globalThis variable
globalThis.myVariable = 3;
console.log('global', globalThis.myVariable);
In Node Js scoping, any variable declared in the root of a module (a particular JS file) is a module-level variable.
var test = 'This string is global to this module';
function foo() {
console.log(test);
}
Node Js also has the Global Namespace Object.
This object is accessible in any module.
global.test = 'This string iscan be accessed by any module via the gloabl namespace object';
function foo() {
console.log(global.test);
}
var global.myVariable = 3;
console.log('myVariable')
I did not check the code though
Why are global variables added to a window object in JavaScript?
var a = 1;
console.log(window.a);
ECMAScript 2015 language specification does not say that declared var or function is added to window global objects.
However, I would like to know why the global variable declared var is added as a property to the window object.
What I'm curious about is that it has nothing to do with ECMAScript language specification?
I used a translator, so please understand if it's weird.
It actually is noted in the specification here, when a variable is assigned to when no such identifier exists:
If IsUnresolvableReference(V) is true, then
a. If V.[[Strict]] is true, throw a ReferenceError
exception.
b. Let globalObj be GetGlobalObject().
c. Return ? Set(globalObj, V.[[ReferencedName]], W, false).
And here, in CreateGlobalVarBinding, which is called when a variable is declared at the top level of a script.
6. Let varDeclarations be the VarScopedDeclarations of script.
...
18. For each String vn of declaredVarNames, do
a. Perform ? env.CreateGlobalVarBinding(vn, false).
The global object may be the window in a browser, or self in a web worker, or the Node global, etc.
I think the reason why var causes properties to be added to the global object (in the example you provided) has to do with how environments are linked in Javascript; they are linked by outer references, yet the global environment has no outer reference. Perhaps the choice to bind them to the global object, as properties, stems from this lack of outer reference in the global environment.
The global scope is the “outermost” scope – it has no outer scope. Its
environment is the global environment. Every environment is connected
with the global environment via a chain of environments that are
linked by outer references. The outer reference of the global
environment is null.
Source: https://2ality.com/2019/07/global-scope.html#the-global-object
In browser-based JavaScript, you can do something like this:
var foo = "foo";
(function() {
var foo = "bar";
console.log(foo);
// => "bar"
console.log(window["foo"]);
// => "foo"
})();
Is there any way to do something similar in Node, which lacks a window object?
If you want an environment agnostic approach, for example, when writing code to work on both the browser and Node.js, you can do something like this in global code at the top of your JavaScript file:
var globalObject = typeof global === "undefined" ? this : global;
and then use globalObject similar to how you would window in the browser context and as you would use global in the Node.js context.
Note that you must declare a variable without var for it to be part of the global object in Node.js.
You can access global variables using global keyword in nodejs.
Note:- There is one rule in nodejs only those variables willl be global variables which dose not have declared using var.
Like if you have declareation like bellow
foo = "sample"; //this you can access using global
But
var foo = "sample"; //this you cann't access using global.
The second one is not actually in global scope, it's local to that module.
From node global docs
In browsers, the top-level scope is the global scope. That means that
in browsers if you're in the global scope var something will define a
global variable. In Node this is different. The top-level scope is not
the global scope; var something inside a Node module will be local to
that module.
I've been toying with node.js lately and I ran into a weird behavior about the usage of this in the global scope of a module.
this is bound to module.exports in the global scope:
console.log(this === exports); // -> true
But this is bound to global in a method scope:
(function() { console.log(this === global); })(); // -> true
This also lead to this confusing behavior:
this.Foo = "Weird";
console.log(Foo); // -> throws undefined
(function() { this.Bar = "Weird"; })();
console.log(Bar); // -> "Weird"
I guess that the solution is to never use this in the global scope and explicitly use extends or global instead, but is there a logic behind all this or is it a bug or limitation in node.js?
The "logic" behind that is, that the value of this always depends on how a function is invoked.
In your case, you have a self-executing anonymous function, there, this always references the global object (non strict mode) or undefined (ES5 strict).
If you want to access the "outer" this value, you could either store a reference before executing that function, like
var outerScope = this;
(function() { outerScope.Bar = "Weird"; })();
console.log(Foo); // -> throws undefined
or re- .bind() the functions scope yourself, like
(function() { this.Bar = "Weird"; }).bind(this)();
In working on a simple CommonJS modules implementation, I had to think about what to do with this in the global scope of the module; it's not addressed by the spec.
I also set it up as the exports object at first, because I thought that would be useful, but later found some code I needed to "modulize" that was using this to get a handle to the global object, so I changed this back to the global object to provide as close of an environment to "normal" as possible for module code.
We can only guess at why node is set up the way it is (or ask the author), but my guess is it was done simply because it seemed like a useful idea, similar to the way you can give the module object an exports property in node and have it reflected in the module's actual exports (this behavior also isn't part of the spec, but doesn't go against it either).
As for the part of your question about this referencing global in functions, as the other answers explain, that's just the way this works; it's not a node-specific behavior, it's a weird javascript behavior.
I don't know if this is the exact intention of Node.js team, but I would be surprised if it was not. Consider this example ran in the dev console of a browser (e.g. chrome):
var x = function(){console.log(this)}
a = {}
a.x = x
a.xx = function(){x()}
a.x()
>> Object
a.xx()
>> DOMWindow
x()
>> DOMWindow
As you can see executing a method without specifying its context sets the context to be the global one. In this case the DOMWindow object.
When you are inside a module your context is the module, but executing a method in it without specifying a context with .call or .apply or obj. will use the global context, global, instead of the local one, module.exports.
what's the difference between Browsers and Node? for instance:
setName.js on Node:
var setName;
setName = function (name) {
return this.name = name;
};
setName("LuLu");
//LuLu
console.log(name);
//undefined
console.log(this.name);
setName.html in browser:
<script>
var setName;
setName = function (name) {
return this.name = name;
};
setName("LuLu");
//LuLu
console.log(name);
//LuLu
console.log(this.name);
</script>
the the second log is different,why?
Node is a JavaScript engine, not a browser. The specific reason that you see undefined in Node, and Lulu in a browser? Differences in the global namespace:
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node this is different. The top-level scope is not the global scope; var something inside a Node module will be local to that module.
In the browser, this is a reference to the window object — the browser's global namespace — for all functions which are invoked unattached to an object (e.g. not like foo.bar()). In Node, this is simply not a reference to the global namespace.
N.B. console.log(this.name) in a Node interpreter will print Lulu, not undefined. That's because, in the REPL only,
> this === global
true
Further reading # How To Node: What is "this?"
Okay, one more edit as prompted by #Šime Vidas' comment regarding this in ES5 strict mode:
In the global context (outside of any function), this refers to the global object, whether in strict mode or not.
When the this keyword occurs inside a function, its value depends on how the function is called.
When a function is called as a method of an object, its this is set to the object the method is called on.
More interesting reading courtesy of Juriy Zaytsev (aka #kangax) in one of his blog posts.
Your browser code has the window host object. Node does not have that host object. When you set this.name, you are actually setting it to the window object aka making a global variable.
window.name === this.name // true