ECMAScript 객체 범위
- 이전 페이지 객체 타입
- 다음 페이지 클래스나 객체 정의
스코프는 변수의 적용 범위를 의미합니다.
공용, 프라이빗, 프로토타입 스코프
개념
전통적인 오브젝트 지향 프로그래밍에서는 공용과 프라이빗 스코프에 주로 집중합니다. 공용 스코프의 객체 속성은 객체 외부에서 접근할 수 있습니다. 즉, 개발자가 객체의 인스턴스를 생성한 후에는 그 공용 속성을 사용할 수 있습니다. 프라이빗 스코프의 속성은 객체 내부에서만 접근할 수 있습니다. 즉, 외부 세계에게는 이러한 속성이 존재하지 않습니다. 이는 클래스가 프라이빗 속성과 메서드를 정의하면 그 자식 클래스도 이러한 속성과 메서드에 접근할 수 없다는 것을 의미합니다.
프로토타입 스코프는 프라이빗 속성과 메서드를 정의하는 데 사용되며, 이 속성과 메서드는 자식 클래스에서도 접근할 수 있습니다.
ECMAScript는 공용 스코프 만 있습니다
ECMAScript에서는 스코프에 대해 논의하는 것은 거의 의미가 없습니다. 왜냐하면 ECMAScript는 공용 스코프만 존재하기 때문입니다. ECMAScript의 모든 객체의 모든 속성과 메서드는 공용입니다. 따라서, 자신의 클래스와 객체를 정의할 때는 매우 조심스럽게 해야 합니다. 기억하세요, 모든 속성과 메서드는 기본적으로 공용입니다!
추천된 해결책
많은 개발자들이 인터넷에서 이 ECMAScript의 문제를 해결할 수 있는 효과적인 속성 스코프 패턴을 제안했습니다.
프라이빗 스코프가 부족하기 때문에, 개발자들은 어떤 속성과 메서드가 프라이빗으로 간주되어야 하는지에 대한 규약을 정했습니다. 이 규약은 속성 앞뒤에 언더스코어를 추가하도록 정의합니다:
obj._color_ = "blue";
이 코드에서, 속성 color은 프라이빗입니다. 주의하세요, 언더스코어는 속성이 공용 속성이라는 사실을 변경하지 않습니다. 그것은 다른 개발자에게 이 속성을 프라이빗으로 보기를 권장합니다.
일부 개발자는 단일 밑줄로 사적인 멤버를 설명하는 것을 좋아합니다. 예를 들어: obj._color.
정적 범위
정적 범위에서 정의된 속성과 메서드는 언제든지 동일한 위치에서 접근할 수 있습니다. 예를 들어 Java에서는 클래스가 객체를 인스턴스화하지 않고도 속성과 메서드에 접근할 수 있습니다. 예를 들어 java.net.URLEncoder 클래스의 encode() 함수는 정적 메서드입니다.
ECMAScript는 정적 범위가 없습니다
정확히 말하면 ECMAScript는 정적 범위가 없습니다. 그러나 그것은 생성자 함수에 속성과 메서드를 제공할 수 있습니다. 기억하시나요? 생성자 함수는 단순한 함수입니다. 함수는 객체이며, 객체는 속성과 메서드를 가질 수 있습니다. 예를 들어:
function sayHello() { alert("hello"); } sayHello.alternate = function() { alert("hi"); } sayHello(); // "hello" 출력 sayHello.alternate(); // "hi" 출력
여기서 alternate() 메서드는 실제로는 sayHello() 함수의 메서드입니다. sayHello()를 일반 함수처럼 호출하여 "hello"를 출력할 수도 있고, sayHello.alternate()를 호출하여 "hi"를 출력할 수도 있습니다. 그러나 alternate()는 sayHello()의 공용 범위 내의 메서드이며, 정적 메서드가 아닙니다.
키워드 this
this의 기능
ECMAScript에서는 가장 중요한 개념 중 하나는 키워드 this의 사용법입니다. 이 키워드는 객체의 메서드에서 사용되며, 항상 메서드를 호출하는 객체를 가리킵니다. 예를 들어:
var oCar = new Object; oCar.color = "red"; oCar.showColor = function() { alert(this.color); }; oCar.showColor(); // "red" 출력
위의 코드에서는 this 키워드가 showColor() 메서드에 사용되고 있습니다. 이 환경에서 this는 oCar와 같습니다. 아래의 코드는 위의 코드와 같은 기능을 수행합니다:
var oCar = new Object; oCar.color = "red"; oCar.showColor = function() { alert(oCar.color); }; oCar.showColor(); // "red" 출력
this를 사용하는 이유
이렇게 this를 사용하는 이유는 객체를 인스턴스화할 때 개발자가 어떤 변수 이름을 사용할지 알 수 없기 때문입니다. this를 사용하면 같은 함수를 여러 곳에서 재사용할 수 있습니다. 아래의 예제를 생각해 보세요:
function showColor() { alert(this.color); }; var oCar1 = new Object; oCar1.color = "red"; oCar1.showColor = showColor; var oCar2 = new Object; oCar2.color = "blue"; oCar2.showColor = showColor; oCar1.showColor(); // "red" 출력 oCar2.showColor(); // "blue" 출력
위의 코드에서는 이전에 this로 함수 showColor()를 정의했고, 두 개의 객체(oCar1과 oCar2)를 생성했으며, 하나의 객체의 color 속성은 "red"로, 다른 하나의 객체의 color 속성은 "blue"로 설정되었습니다. 두 개의 객체는 모두 showColor 속성을 가지고 있으며, 이는 원본 showColor() 함수를 가리킵니다(이곳에는 이름 문제가 없습니다. 전역 함수와 객체 속성은 다릅니다). 각 객체의 showColor()를 호출하면, oCar1의 출력은 "red"이고, oCar2의 출력은 "blue"입니다. oCar1.showColor()를 호출할 때, 함수 내의 this 키워드는 oCar1으로 설정됩니다. oCar2.showColor()를 호출할 때, 함수 내의 this 키워드는 oCar2으로 설정됩니다.
주의하세요, 객체의 속성을 참조할 때는 반드시 this 키워드를 사용해야 합니다. 예를 들어, 아래와 같은 코드를 사용하면 showColor() 메서드가 실행되지 않습니다:
function showColor() { alert(color); };
변수에 객체나 this 키워드를 사용하지 않으면, ECMAScript는 그것을 로컬 변수나 전역 변수로 간주합니다. 그런 다음 이 함수는 color 이름을 가진 로컬이나 전역 변수를 찾습니다. 그러나 찾을 수 없습니다. 결과는 어떻게 될까요? 이 함수는 경고 메시지에서 "null"을 표시합니다.
- 이전 페이지 객체 타입
- 다음 페이지 클래스나 객체 정의