var
allows redeclaring the same variable, which might interfere with browser's built-in functions! (e.g. var console)use strict
helps by e.g. classifying undeclared variables as an error var
ignores block scope, and only follows function scope let
blocks redeclaring the same variable (bug) const
variables cannot be reassigned (TypeError)var
belongs to this windows objectvar
can block browser's built-in functions from functioning properly According to Eloquent JS:
The ability to treat functions as values, combined with the fact that local bindings are re-created every time a function is called, brings up an interesting question. What happens to local bindings when the function call that created them is no longer active?
...
This feature—being able to reference a specific instance of a local binding in an enclosing scope—is called closure. A function that references bindings from local scopes around it is called a closure. This behavior not only frees you from having to worry about lifetimes of bindings but also makes it possible to use function values in some creative ways.
According to mdn:
the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
In essence:
a closure is a combination of an inner function and its lexical scope, which includes the parent or outer scope. It can access its lexical scope even if it is executed outside of it.
The set of bindings visible inside a block is determined by the place of that block in the program text. Each local scope can also see all the local scopes that contain it, and all scopes can see the global scope. This approach to binding visibility is called lexical scoping. ~E. JS
The lexing phase of compilation determines where and how all identifiers are declared, and thus how they will be looked up during execution. This is the same mechanism which results in “hoisting” variables. The variables are not actually moved within the source code, the declarations simply occur during the lexing phase and so the JavaScript engine is aware of these before execution.
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`
const divMaker = tagMaker('div');
//
divMaker('hello') // '<div>hello</div>'
divMaker('codestates') // '<div>codestates</div>'
//
const anchorMaker = tagMaker('a');
anchorMaker('go') // '<a>go</a>'
anchorMaker('urclass') // '<a>urclass</a>'
closure module pattern
private methods & properties (ref)
var myModule = (function() {
'use strict';
var _privateProperty = 'Hello World';
function _privateMethod() {
console.log(_privateProperty);
}
return {
publicMethod: function() {
_privateMethod();
}
};
})();
//.
myModule.publicMethod(); // outputs 'Hello World'
console.log(myModule._privateProperty); // is undefined protected by the module closure
myModule._privateMethod(); // is TypeError protected by the module closure
Revealing module pattern (ref)
Using the return statement we can return a object literal that 'reveals' only the methods or properties we want to be publicly available
var myModule = (function() {
'use strict';
var _privateProperty = 'Hello World';
var publicProperty = 'I am a public property';
function _privateMethod() {
console.log(_privateProperty);
}
function publicMethod() {
_privateMethod();
}
return {
publicMethod: publicMethod,
publicProperty: publicProperty
};
})();
//.
myModule.publicMethod(); // outputs 'Hello World'
console.log(myModule.publicProperty); // outputs 'I am a public property'
console.log(myModule._privateProperty); // is undefined protected by the module closure
myModule._privateMethod(); // is TypeError protected by the module closure
<!DOCTYPE html>
<html>
<body>
<button class="toggle">toggle</button>
<div class="box" style="width: 100px; height: 100px; background: red;">box</div>
<script>
var box = document.querySelector('.box');
var toggleBtn = document.querySelector('.toggle');
var toggle = (function () {
var isShow = false;
return function () {
if(!isShow) box.style.display="none";
else {box.style.display="block"; changeText()}
isShow = !isShow;
console.log(isShow);
};
})();
var changeText = (function(){
var isNew= false;
return function () {
if (!isNew) box.textContent="oldBox";
else box.textContent="newBox";
isNew = !isNew;
}
})();
// ② 이벤트 프로퍼티에 클로저를 할당
toggleBtn.onclick = toggle;
</script>
</body>
</html>