Scoping rules
The main difference is scoping rules. Variables declared by var
keyword are scoped to the immediate function body (hence the function scope) while let
variables are scoped to the immediate enclosing block denoted by { }
(hence the block scope).
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar); // Foo Bar
{
var moo = "Mooo"
let baz = "Bazz";
console.log(moo, baz); // Mooo Bazz
}
console.log(moo); // Mooo
console.log(baz); // ReferenceError
}
run();
The reason why let
keyword was introduced to the language was function scope is confusing and was one of the main sources of bugs in JavaScript.
Take a look at this example from another stackoverflow question:
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
My value: 3
was output to console each time funcs[j]();
was invoked since anonymous functions were bound to the same variable.
People had to create immediately invoked functions to capture correct values from the loops but that was also hairy.
Hoisting
While variables declared with var
keyword are hoisted (initialized with undefined
before the code is run) which means they are accessible in their enclosing scope even before they are declared:
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
let
variables are not initialized until their definition is evaluated. Accessing them before the initialization results in a ReferenceError
. The variable is said to be in "temporal dead zone" from the start of the block until the initialization is processed.
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
Creating global object property
At the top level, let
, unlike var
, does not create a property on the global object:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // not allowed to be globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
Redeclaration
In strict mode, var
will let you re-declare the same variable in the same scope while let
raises a SyntaxError.
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
This article about Javascript Strict Mode might interest you: John Resig - ECMAScript 5 Strict Mode, JSON, and More
To quote some interesting parts:
Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a "strict" operating context. This strict context prevents certain actions from being taken and throws more exceptions.
And:
Strict mode helps out in a couple ways:
- It catches some common coding bloopers, throwing exceptions.
- It prevents, or throws errors, when relatively "unsafe" actions are taken (such as gaining access to the global object).
- It disables features that are confusing or poorly thought out.
Also note you can apply "strict mode" to the whole file... Or you can use it only for a specific function (still quoting from John Resig's article):
// Non-strict code...
(function(){
"use strict";
// Define your library strictly...
})();
// Non-strict code...
Which might be helpful if you have to mix old and new code ;-)
So, I suppose it's a bit like the "use strict"
you can use in Perl (hence the name?): it helps you make fewer errors, by detecting more things that could lead to breakages.
Strict mode is now supported by all major browsers.
Inside native ECMAScript modules (with import
and export
statements) and ES6 classes, strict mode is always enabled and cannot be disabled.
Best Answer
Introducing npx: an npm package runner
NPM
- Manages packages but doesn't make life easy executing any.NPX
- A tool for executing Node packages.NPM
by itself does not simply run any package. it doesn't run any package in a matter of fact. If you want to run a package using NPM, you must specify that package in yourpackage.json
file.When executables are installed via NPM packages, NPM links to them:
./node_modules/.bin/
directory.bin/
directory (e.g./usr/local/bin
) on Linux or at%AppData%/npm
on Windows.Documentation you should read
NPM:
One might install a package locally on a certain project:
Now let's say you want NodeJS to execute that package from the command line:
The above will fail. Only globally installed packages can be executed by typing their name only.
To fix this, and have it run, you must type the local path:
You can technically run a locally installed package by editing your
packages.json
file and adding that package in thescripts
section:Then run the script using
npm run-script
(ornpm run
):NPX:
npx
will check whether<command>
exists in$PATH
, or in the local project binaries, and execute it. So, for the above example, if you wish to execute the locally-installed packagesome-package
all you need to do is type:Another major advantage of
npx
is the ability to execute a package which wasn't previously installed:The above example will generate a
react
app boilerplate within the path the command had run in, and ensures that you always use the latest version of a generator or build tool without having to upgrade each time you’re about to use it.Use-Case Example:
npx
command may be helpful in thescript
section of apackage.json
file, when it is unwanted to define a dependency which might not be commonly used or any other reason:Call with:
npm run serve
Related questions: