IT/WEB

[JavaScript/jQuery] 코드 리뷰 내용 정리 (1)

개발자 두더지 2020. 9. 28. 13:08
728x90

1. 

JavaScript의 var은 함수 스코프(Scope)이므로 의도에 반하는 결과가 발생할 수 있다. 따라서 var의 사용은 삼가하는 편이 좋다. ( 이번에는 사용하지 않았으므로 영향이 없으나, var로 선언한 변수를 클로저로 사용하면 좋지 않은 결과를 얻을 수 있다.) 

1) 좋지 않은 예

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);


// NG
for (var key in data){ // NG: var로는 기대대로 나오지 않는다.
  // 1초후에 처리하고자함
	setTimeout(function(){
  	alert(key); // 클로저를 사용하여 function의 밖에 있는 변수n을 참고. a, b, c (임의의 순서)로 나왔으면 한다.
  }, 1000);
}

a, b, c (임의의 순서)가 알림창으로 뜨길 바랐지만 결과는 c가 세 번 나옴

2) 결론

최근 버전의 브라우저는 블록 스코프(Scope)의 const나 let가 있으므로 이것을 사용하는 것이 좋다.

위의 코드에서 const를 사용하는 것만으로 원했던 결과가 출력되는 것을 확인할 수 있다.

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);


for (const key in data){ // OK
  // 1초 후에 처리된다.
	setTimeout(function(){
  	alert(key); // 클로저를 사용해 function외에 있는 변수 n을 참고. a, b, c (임의의 순서)가 출력되길 바란다.
  }, 1000);
}

 

2. 

Object형을 for in으로 처리하면 좋지 않다. Object.prototype가 설정되어 있어 있으면 데이터에 관계없이 열거해버리고 만다. for-in를 사용하는 경우 hasOwmProperty등으로 체크하거나 for 루프 부분을 for of로 처리하여 사용할 필요가 있다.

1) 좋지 않은 예

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);

Object.prototype.mykeys = function(){ return Object.keys(this); }

console.log(data.mykeys()) // 이렇게 사용하거나...

for (const key in data){ // NG: for in 으로 하면 Object.prototype의 키도 섞인다.
  // 1후에 처리한다.
	setTimeout(function(){
  	alert(key);
  }, 1000);
}

a, b, c 이외에 mykeys도 알림창에 뜬다.

2) 결론

hasOwnProperty로 체크하거나, Object.keys(...)로 취급해 for 루프 혹은 for of 로 처리하는 것이 좋다.

① for 루프를 사용하는 경우

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);

Object.prototype.mykeys = function(){ return Object.keys(this); }

console.log(data.mykeys())

const dataKeys = Object.keys(data);
for (let i=0; i < dataKeys.length; ++i){
	const key = dataKeys[i]
	setTimeout(function(){
  	alert(key);
  }, 1000);
}

 ② for of를 사용하는 경우

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);

Object.prototype.mykeys = function(){ return Object.keys(this); }

console.log(data.mykeys())

for(const key of Object.keys(data)){
	setTimeout(function(){
  	alert(key);
  }, 1000);
}

 ※ jQuery를 사용하는 경우

$.each를 사용해도 같은 처리를 할 수 있으나 hasOwnProperty로 체크할 필요가 있다.

const data = JSON.parse(`{
  "a": 1,
  "b": 2,
  "c": 3
}`);

Object.prototype.mykeys = function(){ return Object.keys(this); }

console.log(data.mykeys())

$.each(data, function(key, value){
  if(!data.hasOwnProperty(key)){
  	return; // for이 아닌 $.each로 호출하고 있는function이므로continue가 아닌return으로
  }
	setTimeout(function(){
  	alert(key);
  }, 1000);
})

 

3. 

JavaScript에 있어서 HTML과 결합에는 문자열 결합 (예를 들어, "<td>"+ value +"</td>"과 같은) 틀린 표현이다.

이와 동일한 작성법으로 jQuery를 사용하는 경우는 $("<td>").text(value) 등이 있다. 

( 참고로 JavaScript의 경우는 document.createElement 로 만든 Element 데이터에 대해 textContent로 설정하는 방식을 사용한다.) 

그러나 더욱 간단하게 작성할 수 있도록 mustache등의 템플릿 지원 라이브러리 등이 있다. 아무튼 jQuery를 사용한다면, 

$('#tbody').append("<td>" + key + " : " + value[key] + "</td>");

위 표현을 아래와 같이 바꿀 수 있다.

$('#tbody').append($('td').text(key + " : " + value[key]));
 
728x90