property (프로퍼티)
객체의 특성(예: 색깔)(feat.객체지향)
자바스크립트의 객체는 key와 value로 구성된 property들의 집합이다. 프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든값을 사용할 수 있다.
프로퍼티 : key + value
key : 빈 문자열을 포함하는 모든 문자열 또는 symbol값
value: 모든값
프로퍼티 키에 문자열이나 심볼 값 이외의 값을 지정하면 타입이 변환되어 문자열이 된다. 프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다.
method
객체의 능력 (예: 걷기)(feat.객체지향)
프로퍼티값이 함수일 경우,
객체는 데이터를 의미하는 프로퍼티와 데이터를 참조하고 조작할 수 있는 동작을 의미하는 메소드로 구성된 집합이다.
생성자함수(constructor)
생성자는 인스턴스화되는 순간(객체 인스턴스가 생성되는 순간) 호출된다. 생성자는 해당 클래스의 메서드이다.
생성자 함수를 통해 생성된 객체를 인스턴스(instance)라 한다
자바스크립트는 오브젝트 생성자 함수 이외에도 String,Number,Boolean,Array,Date 등의 빌트인 생성자 함수를 제공한다. 일반 함수와 생성자 함수를 구분하기위해 새ㅑㅇ성자 함수의 이름은 파스칼케이스(PascalCase)를 사용하는 것이 일반적이다.
객체 리터럴 방식과 object 생성자 함수 방식으로 객체를 생성하는 것은 프로퍼티 값만 다른 여러 개의 객체를 생성할 떄 불편하다.
var person1 = {
name: 'Lee',
gender: 'male',
sayHello: function () {
console.log('Hi! My name is ' + this.name);
}
};
var person2 = {
name: 'Kim',
gender: 'female',
sayHello: function () {
console.log('Hi! My name is ' + this.name);
}
};
생성자 함수를 사용하면 마치 객체를 생성하기 위한 템플릿(클래스)처럼 사용하여 프로퍼티가 동일한 객체 여러개를 간편하게 생성할 수 있다.
// 생성자 함수
function Person(name, gender) {
var married = true;
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! My name is ' + this.name);
};
console.log(this) // this확인용
}
// 인스턴스의 생성
var person1 = new Person('Lee', 'male');
// person 1 = Person {name: "lee", gender: "male", sayHello: ƒ}
// this값은 person1이 된다.
var person2 = new Person('Kim', 'female');
// person 2 = Person {name: "kim", gender: "Female", sayHello: ƒ}
// this 값은 person2가 된다.
console.log('person1: ', typeof person1);
console.log('person2: ', typeof person2);
console.log('person1: ', person1);
console.log('person2: ', person2);
person1.sayHello(); //Hi! My name is lee
person2.sayHello(); //Hi! My name is kim
외부에서 Person의 메소드,키를 참조할 수 있다.
console.log(person.gender); //'male'
console.log(person.married); // undefined
- 생성자 함수 이름은 일반적으로 대문자로 시작한다. 이것은 생성자 함수임을 인식하도록 도움을 준다.
- 프로퍼티 또는 메소드명 앞에 기술한 this는 생성자 함수가 생성할 인스턴스(instance)를 가리킨다.
- this에 연결(바인딩)되어 있는 프로퍼티와 메소드는 public(외부에서 참조 가능)하다.
- 생성자 함수 내에서 선언된 일반 변수는 private(외부에서 참조 불가능)하다. 즉, 생성자 함수 내부에서는 자유롭게 접근이 가능하나 외부에서 접근할 수 없다.
즉, 기존 함수와 동일한 방법으로 생성자 함수를 선언하고 new 연산자를 붙여서 호출하면 해당 함수는 생성자 함수로 동작한다.
자바스크립트의 경우 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프(Lexical scope)는 함수를 선언할 때 결정된다. this 바인딩과 혼동하지 않도록 주의하기 바란다.
암묵적전역(implicit global)
var x = 10; // 전역 변수
function foo () {
// 선언하지 않은 식별자
y = 20;
console.log(x + y);
}
foo();
선언하지 않은 식별자 y는 마치 선언된 변수처럼 동작한다. 이는 선언하지 않은 식별자에 값을 할당하면 전역 객체의 프로퍼티가 되기 때문이다.하지만 y는 변수 선언없이 단지 전역 객체의 프로퍼티로 추가되었을 뿐이다. 따라서 y는 변수가 아니다. 따라서 변수가 아닌 y는 변수 호이스팅이 발생하지 않는다.
즉시 실행 함수(IIFE, Immediately-Invoked Function Expression)
전역변수를 사용을 억제하기 위해 사용한다. 이 방법을 상요하면 전역변수를 만들지 않으므로 라이브러리 등에 자주 사용된다. 즉시 실행 함수는 즉시 실행되고, 그 후 전역에서 바로 사라진다.
(function (){}()) // IIFE 형태
(function () {
var MYAPP = {};
MYAPP.student = {
name: 'Lee',
gender: 'male'
};
console.log(MYAPP.student.name);
}());
console.log(MYAPP.student.name);
//VM466:1 Uncaught ReferenceError: MYAPP is not defined
at <anonymous>:1:13
함수호출방식
- 함수 호출
- 메소드 호출
- 생성자 함수 호출
- apply/call/bind 호출
var foo = function () {
console.dir(this);
};
// 1. 함수 호출
foo(); // window
// window.foo();
// 2. 메소드 호출
var obj = { foo: foo };
obj.foo(); // obj
// 3. 생성자 함수 호출
var instance = new foo(); // instance
// 4. apply/call/bind 호출
var bar = { name: 'bar' };
foo.call(bar); // bar
foo.apply(bar); // bar
foo.bind(bar)(); // bar
this는 전역객체(Global object)에 바인딩된다. 전역함수는 물론이고 심지어 내부함수의 경우도 this는 외부함수가 아닌 전역객체에 바인딩된다.
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
또한 메소드의 내부함수일 경우에도 this는 전역객체에 바인딩된다.
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
}
};
obj.foo();
콜백함수의 경우에도 this는 전역객체에 바인딩된다.
var value = 1;
var obj = {
value: 100,
foo: function() {
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
내부함수는 일반함수, 메소드, 콜백함수 어디에서 선언되었든 관계없이 this는 전역객체를 바인딩한다.
회피방법 1. var this = that
var value = 1;
var obj = {
value: 100,
foo: function() {
var that = this; // Workaround : this === obj 함수 내에 저장해준다
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
console.log("bar's that: ", that); // obj
console.log("bar's that.value: ", that.value); // 100
}
bar();
}
};
obj.foo();
회피방법2. apply, call, bind 메소드
var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
function bar(a, b) {
console.log("bar's this: ", this); // obj
console.log("bar's this.value: ", this.value); // 100
console.log("bar's arguments: ", arguments);
}
bar.apply(obj, [1, 2]);
bar.call(obj, 1, 2);
bar.bind(obj)(1, 2);
}
};
obj.foo();
함수가 객체의 프로퍼티 값이면 메소드로서 호출된다. 이때 메소드 내부의 this는 해당 메소드를 소유한 객체, 즉 해당 메소드를 호출한 객체에 바인딩된다.
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();
프로토타입
[[Prototype]]
- 함수를 포함한 모든 객체가 가지고 있는 인터널 슬롯이다.
-
객체의 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키며 함수 객체의 경우 Function.prototype를 가리킨다. 그 이유에 대해서는 4.2 생성자 함수로 생성된 객체의 프로토타입 체인을 참조하기 바란다.
prototype 프로퍼티
- 함수 객체만 가지고 있는 프로퍼티이다.
-
함수 객체가 생성자로 사용될 때 이 함수를 통해 생성될 객체의 부모 역할을 하는 객체(프로토타입 객체)를 가리킨다.
console.log(Person.prototype === foo.__proto__);
// Person의 자식이 누구야? === foo의 부모가 누구야?
프로토타입체인(Prototype chain)
자바스크립트는 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티 또는 메소드가 없다면 [[Prototype]]이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다. 이것을 프로토타입 체인이라 한다.
function Person(name) {
this.name = name;
}
var foo = new Person('Lee');
// 부모자식은 객체의 프로퍼티 안의 객체의 프로퍼티 같은 개념예시. {{}}
// Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다.
// Person() 의 자식을 생성(?)한거 누구야? === Person();
console.log(Person.prototype.constructor === Person);
// foo 객체를 생성한 객체는 Person() 생성자 함수이다.
// foo를 생성(?)한거 누구야? === Person
console.log(foo.constructor === Person);
// Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다.
// Person() 을 생성(?)한거 누구야? === Function
console.log(Person.constructor === Function);
console.dir(Function) 을 콘솔창에 찍어보면 알 수 있다.

출처 및 레퍼런스
https://developer.mozilla.org/ko/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
객체지향 자바스크립트 개요
비록 다른 객체지향적인 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, JavaScript는 강력한 객체지향 프로그래밍 능력들을 지니고 있다.
developer.mozilla.org
this | PoiemaWeb
자바스크립트의 this keyword는 Java와 같은 익숙한 언어의 개념과 달라 개발자에게 혼란을 준다. Java에서의 this는 인스턴스 자신(self)을 가리키는 참조변수이다. this가 객체 자신에 대한 참조 값을 가지고 있다는 뜻이다. 주로 매개변수와 객체 자신이 가지고 있는 멤버변수명이 같을 경우 이를 구분하기 위해서 사용된다. 자바스크립트의 경우 함수 호출 패턴에 따라 어떤 객체를 `this`에 바인딩할 지가 결정된다. 즉, 함수 호출 패턴에
poiemaweb.com
https://ko.javascript.info/object-methods
메서드와 'this'
ko.javascript.info
댓글