(흔히 밧줄이나 장비를 이용하여) 들어[끌어]올리다.
Javascript의 특징으로 함수나 변수를 말 그대로 끌어 올린다.
test();
function test() {
console.log('hello');
}
// hello
console.log(foo);
var foo = 'world';
// undefined
Javascript의 특징인 hoisting으로 인한 문제가 발생할 수 있다.
아래와 같은 예제가 있다.
// <input type="text" id="email">
// <input type="text" id="name">
// <input type="text" id="phone">
// <div id="notice"></div>
function show(text) {
document.getElementById('notice').innerHTML = text;
}
function set() {
var data = [
{ id: 'email', text: 'email' },
{ id: 'name', text: 'name' },
{ id: 'phone', text: 'phone' },
];
for (var i = 0; i < data.length; i++) {
var item = data[i];
document.getElementById(item.id).onfocus = function () {
show(item.text);
};
}
}
set();
위 코드의 원하는 동작은 아래와 같다.
그러나 이 코드에는 문제가 있다. 어떤 문제가 있을까? item 변수의 값이 배열의 마지막 값으로 덮어 씌워 지기 때문에 onfocus이벤트가 발생하면 항상 ‘phone’이 출력되게 된다. 왜 그럴까 javascript의 hoisting 때문이다. var는 block scope가 아닌 function scope이기 때문에 사실상 function의 최상단에 선언 되어진다. 이것이 hoisting이다. 그렇다면 해결 방법은 무엇이 있을까? 5가지 정도가 있는것 같다.
let 은 block scope 이기 때문에 for문 내에서 존재한다. 그렇기 때문이 값이 덮어 쓰일 걱정이 없다.
function show(text) {
document.getElementById('notice').innerHTML = text;
}
function set() {
var a = [
{id: 'email', text: 'email'},
{id: 'name', text: 'name'},
{id: 'phone', text: 'phone'},
];
for (var i = 0; i < a.length; i++) {
let item = a[i];
document.getElementById(item.id).onfocus = function() {
show(item.text);
};
}
}
set();