Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

javascript - The 'this' keyword behaves differently in Nodejs and browser

I have this piece of code :

var obj1;
var obj2;

function x() {
    obj1 = this;
}

function y() {
    obj2 = this;
}

x();
y();

console.log(obj1 === obj2);
console.log(obj1 === this);

I ran this code in NodeJS using command line : node app.js and ran as a script in Chrome browser

The result : in NodeJS, the result was : true false NodeJS result

In Chrome browser, the result was : true true Browser result

How can this happened ? can anyone explain what really going on under the hood ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the browser, running in the global scope, this is always window in your example

var obj1;
var obj2;

function x() {
    obj1 = this; // window
}

function y() {
    obj2 = this; // window
}

x();
y();

console.log(obj1 === obj2);  // window === window = true
console.log(obj1 === this);  // window === window = true

This is not how it works in Node. In Node.js all modules (script files) are executed in their own closure while browsers execute all script files directly within the global scope.

In other words, in just about any file running in Node, this will just be an empty object, as Node wraps the code in an anonymous function that is called immediately, and you'd access the global scope within that context with GLOBAL instead.

This is also mentioned in the Globals documentation:

Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

However, when calling a function without a specific context in Node.js, it will normally be defaulted to the global object - The same GLOBAL mentioned earlier, as it's execution context.

So outside the functions, this is an empty object, as the code is wrapped in a function by Node, to create it's own execution context for every module (script file), while inside the functions, because they are called with no specified execution context, this is the Node GLOBAL object

In Node.js you'd get

var obj1;
var obj2;

function x() {
    obj1 = this; // GLOBAL
}

function y() {
    obj2 = this; // GLOBAL
}

x();
y();

console.log(obj1 === obj2);  // GLOBAL === GLOBAL = true
console.log(obj1 === this);  // GLOBAL === {} = false

Where the last this is indeed an empty object, as explained above


For completeness, it's worth noting that in strict mode, you'd get the same result in a browser (true, false) as in Node, but that's because the variables are just the opposite of what they are in Node

"use strict"

var obj1;
var obj2;

function x() {
    obj1 = this; // undefined
}

function y() {
    obj2 = this; // undefined
}

x();
y();

console.log(obj1 === obj2);  // undefined === undefined = true
console.log(obj1 === this);  // undefined === window = false

This is because the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed").
For a normal function in non-strict mode, this is always an object, and it's always the global object if called with an undefined or null this-value, i.e. without a specific execution context.

Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard, because the global object provides access to functionality that "secure" JavaScript environments must restrict.

Thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be undefined inside functions, as shown above, but this will still be the window in the global scope.

The same thing happens in strict-mode in Node.js, where this inside the functions is no longer GLOBAL but undefined, and this outside the functions will still be the same empty object, and the end result will still be true, false, but the value of this will be different in strict-mode in Node.js as well.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...