객체 리터럴을 사용할 수 있는 상황에서는 new Object() 생성자를 쓸 이유가 없다.


하지만 다른사람이 작성한 레거시 코드를 물려받을 수도 있기 때문에 이 생성자의 '기능' 하나를 알아 둘 필요가 있다.



Object()는 인자를 받을 수 있는데 이 값에 따라 맞는 생성자로 객체를 생성한다.

//빈 객체
var o = new Object();
console.log(o.constructor === Object);    // true

// 숫자 객체
var o = new Object(1);
console.log(o.constructor === Number);    // true
console.log(o.toFixed(2));    // "1.00"

// 문자열 객체
var o = new Object("I am string");
console.log(o.constructor === String);    // true
console.log(typeof o,substring);            // "function"

// 불린 객체
var o = new Object(true);
console.log(o.constructor === Boolean);    // true



따라서 어떤 상황이 발생할 지 모르므로 Object로는 객체를 생성하지 말자.




객체 생성 시, 

생성자(Array(), Object(), String(), Boolean(), Number()) 사용을 자제하고 대신 리터럴 표기법을 사용하여 생성하자.

// 리터럴 사용
var car = { goes: "far" };

// 생성자 사용
var car = new Object();
car.goes = "far";



생성자를 사용해서 객체를 생성하면 득이 되는 것이 없다.

  1. 코드가 더 길어진다.
  2. 유효범위 판별 작업을 해야 한다.
    동일한 이름(Object()) 함수가 새로 정의되어 있는지 여부를 유효범위 체인을 따라가며 확인할 필요가 없다.




자바스크립트에서 eval()은 사악한(evil) 함수이다.


동적인 프로퍼티에 접근할 때에는 대괄호 표기법이 더 간단하고 좋다.


//안티 패턴
var obj = {name:"javascript"};
var property = "name";
alert(eval("obj."+property))
// 권장 패턴
var obj = {name:"javascript"};
var property = "name";
alert(obj[property])






setInterval(), setTimeout(), Function() 인자로 문자열을 넘기는 것도 eval()과 비슷하다.


반드시 eval()을 사용해야 한다면 

  1. new Function()으로 감싸서 사용하자.
    Function() 생성자로 감싸게되면 유효영역이 새로 만들어져 var 선언 변수들이 전역에 선언되는 경우를 막을 수 있다.
  2. eval() 호출을 즉시실행 함수로 감싸서 실행되도록 하자.
console.log(typeof un);    // undefined
console.log(typeof deux);    // undefined
console.log(typeof trois);    // undefined

var jsstring = "var un = 1; console.log(un);";
eval(jsstring);    // "1"

jsstring = "var deux = 2; console.log(deux);";
new Function(jsstring)();    // "2"    // 생성자로 생성한 함수를 바로 호출한다. 
     // 유효범위가 새로 생기므로 deux는 로컬변수가 된다.

jsstring = "var trois = 3; console.log(trois);";
(function() {
   eval(jsstring);
}()); // "3" // eval()을 함수로 감싸고 그 함수를 즉시 호출한다. trois 또한 함수의 로컬변수가 된다.

console.log(typeof un);        // "1"
console.log(typeof deux);   // "undefined"
console.log(typeof trois);    // "undefined"


eval()과 Function()의 또다른 차이


eval()은 자신의 유효범위 다음으로 자신을 감싸는 유효범위를 바라보고 있다.

하지만 Function()은 자신의 유효범위 다음으로 전역 유효범위를 바라보고 있다.

따라서 eval()은 유효범위 체인에 간섭을 일으킬 수 있다.

(function () {
	var local = 1;
	eval("local = 3; console.log(local);");    // 3이 출력된다.
	console.log(local);    // 3이 출력된다. 감싸고있는 함수의 local 변수의 값을 바꿔버린다.
}())

(function () {
	var local = 1;
	Function("console.log(typeof local);")();    // undefined가 출력된다. 
	// Function 객체의 상위 유효범위는 전역.
	// 전역에 local 변수가 없으므로 undefined.
}())

'WEB > javascript' 카테고리의 다른 글

객체 생성자의 함정  (0) 2012.07.22
자바스크립트 리터럴 표기법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10
myname = "global";
function func() {
	alert(myname);
	var myname = "local";
	alert(myname);
}
func();


의도된 결과는




였을 것이다.


하지만. 자바스크립트에는 hoisting이라는 성질이 있다.


myname = "global";
function func() {
var myname;            // undefined
alert(myname);
myname = "local";
alert(myname);
}
func();



myname 라는 변수의 선언이 scope의 맨 위로 올려져 undefined 값으로 설정된다.


따라서 결과는







'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10
객체지향 언어  (0) 2012.07.09



모든 자바스크립트는 실행환경에서 전역 객체(global object)가 존재한다.

변수에 값을 assign 할 경우 var 선언을 하지 않으면 전역 변수로 생성된다.


myglobal = "hello";    // 안티패턴 myglobal : 암묵적 전역 변수
console.log(myglobal);           // "hello"
console.log(window.myglobal);    // "hello"
console.log(window["myglobal"];  // "hello"
console.log(this.myglobal);      // "hello"


실수하기 쉬운 전역변수 선언

function sum(x, y) {
	// 안티 패턴 result : 암묵적 전역
	result = x + y;
	return result;
}

//안티패턴 b : 암묵적 전역 변수
function foo() {
	var a = b = 0;
}


전역변수의 문제점



  • 광고같은 서드파티 스크립트들로인해 중요한 변수가 덮어쓰여지거나 삭제 될 수 있다.


 위의 코드는 엄밀히 말하면 전역 객체에 변수가 아닌 프로퍼티가 result가 추가되는 것이다. (var 선언이 없기 때문)

프로퍼티는 delete 연산자로 삭제 가능하지만 변수는 불가능 하므로 주의해야 한다.


예를들어, 함수내에서 살아있어야 하는 변수를 전역 프로퍼티로 잘못 생성하면 서드파티 코드에서 우연히 삭제할 가능성이 있기 때문이다.







'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
strict mode  (0) 2012.07.10
객체지향 언어  (0) 2012.07.09


ECMAScript 5에 추가된 기능.


실제로 기능을 추가한 것이 아니라 제거함으로써 프로그램을 더 간단하게 만들고 오류 발생 가능성을 낮춘것.

예를들어 with를 스트릭트 모드에서 쓰면 에러가 발생한다.

function my() {
	'use strict'
	with(o) {    // error
	}
}


'use strict'  유효범위는 함수, 전역, 또는 eval()로 전달된 문자열.


ES는 추후에 스트릭트 모드만 지원하려고 계획중이다.

따라서 ES5는 개발자에게 strict mode에서 동작하는 코드를 작성하도록 권장하는 과도적인 버전.



네이티브 객체 : ECMAScript 표준에 정의된 객체

네이티브 객체는 내장객체(예를들면, Array나 Date) 또는 사용자 정의 객체(var o={};)로 분류된다.



호스트 객체 : 호스트환경(예를 들면, 브라우저 환경)에서 정의된 객체

호스트 객체의 예로는 window 객체나 모든 DOM 객체를 들 수 있다.





어떤 객체가 호스트 객체인지 궁금하다면?

코드를 브라우저가 아닌 다른 환경에서 실행시켜 보면 된다. 

만약 잘 동작한다면 네이티브 객체만을 사용하고 있는 것이다.



'WEB > javascript' 카테고리의 다른 글

자바스크립트 리터럴 표기법  (0) 2012.07.22
eval() 안전하게 사용하는 방법  (0) 2012.07.22
호이스팅(hoisting): 분산된 var 선언의 문제점  (0) 2012.07.12
자바스크립트 전역변수  (0) 2012.07.10
strict mode  (0) 2012.07.10

+ Recent posts