-
[JS] 객체 지향 - 표준내장객체와 확장, 데이터 타입, 참조생활코딩/ 2020. 9. 7. 16:27
[강의 출처] opentutorials.org/course/743
표준 내장 객체(Standard Built-in Object)
-자바스크립트에서 공식적으로 지원하는 기본 객체(↔사용자 정의 객체)
-Object, Function, Array, String, Boolean, Number, Math, Date, RegExp
일반적으로 array를 인풋으로 함수를 정의하면 이렇다.
var arr = new Array('a', 'b', 'c', 'd', 'e'); function getRandomValueFromArray(arr){ var index = Math.floor(Math.random()*arr.length); return arr[index]; }
(prototype을 이용한 배열 확장) 표준 내장 객체인 array 객체 모두에서 위 함수를 메소드로 사용할 수 있도록 코드를 변경하면
Array.prototype.randomElement = function(){ var index = Math.floor(this.length*Math.random()); return this[index]; } arr = new Array('a', 'b', 'c', 'd', 'e'); console.log(arr.randomElement()); // 랜덤하게 원소 추출 가능
일반적인 정의 방식에 비해 간결하고, 목적이 분명하게 드러난다.
어떤 객체들이 공통적으로 사용해야 하는 로직이 있다면 프로토타입에 포함시키는 것도 하나의 방법이 될 수 있다.
Object(객체)
-JS에서 값을 저장하는 기본적인 단위이자 모든 객체의 prototype
-Object.prototype.method 형태로 확장하면 모든 객체에 영향을 줄 수 있어 주의를 요한다.
-Object 객체에만 적용되는 메소드를 만들려면 Object.method 형태로 작성한다.
-객체 관련 레퍼런스는 이쪽을 참고: developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object
-Object 객체를 확장해서 의도치 않은 결과를 얻게 되는 예시
Object.prototype.contain = function(needle){ for(var name in this){ if(this[name] === needle){ return true; } } return false; } var o = {'name': 'a', 'city': 'A'} var k = ['a', 'b', 'c']; for(var name in o){ console.log(name); } // name, city, contain /* Object의 prototype에 추가했기 때문에 모든 객체에 contain프로퍼티가 추가되는 결과 발생 * 따라서 메소드를 만들 때는 공통의 로직이 필요한 최소 단위에만 적용하는 것이 바람직함 */
-.hasOwnPropery 메소드로 상속 받은 프로퍼티가 아닌 고유 프로퍼티인지 여부를 확인가능
for (var name in o){ if(o.hasOwnProperty(name)){ console.log(name); } } // name, city
데이터 타입
-데이터 타입은 원시 데이터 타입(기본 데이터)과 객체 데이터 타입(참조 데이터 타입)으로 구분된다.
-원시 데이터 타입(primitive data type)에는 숫자(Number), 문자열(String), 불리언(Boolean), null, undefined가 있으며,
-원시 데이터 타입을 객체처럼 다룰 수 있도록 하는 객체를 레퍼객체(wrapper object)라고 부른다.
// 원시 데이터 타입의 경우 var str = 'string'; // 원시 데이터 타입으로 정의했기 때문에 str.prop = 'property'; // 프로퍼티를 가질 수 없다 console.log(str.prop); // undefined // 객체 데이터 타입의 경우 var objStr = new String('string'); // 레퍼 객체를 통해 객체로 정의했기 때문에 objStr.prop = 'property'; // 프로퍼티를 가질 수 있다 console.log(objStr.prop); // 'property'
-레퍼객체는 아래처럼 원시 데이터 타입에서 메소드를 사용하는 경우
var str = 'string'; /* 레퍼객체가 임시적으로 * var str = new String('string'); * 와 같은 효과를 내준다 */ console.log(str.length); // 6
str.legnth 구문이 호출될 때 레퍼 객체가 var str = new String('string'); 처럼 임시로 정의되고, 사용이 끝나면 제거된다.
-JS는 레퍼객체를 기본적으로 지원해주는 언어로 위와 같은 경우 사용자가 별도로 정의하지 않아도 된다.
-객체.메소드로 표기할 때 '.' 기호의 명칭은 Object Access Operator
-null, undefined는 레퍼 객체가 없다.
복제와 참조
-변수에 담겨 있는 데이터가 원시 데이터 타입인 경우, 할당(assignment) 연산시('=') 복제된다.
var a = 1; var b = a; b = 2; console.log(a); // 1 /* b의 값을 수정해도 원본 데이터 a에는 영향을 주지 않는다 */
-변수에 담겨 있는 데이터가 객체 데이터 타입인 경우, 할당 연산시 참조(Reference)된다.
var a = {'id': 1}; var b = a; b.id = 2; console.log(a.id); // 2 /* b의 값을 수정하면 b가 참조하고 있는 a의 값도 변경된다 */
-변수에 값이 새롭게 할당되면 기존값(참조거나 복제거나 상관없이)에는 영향을 주지 않는다.
var a = {'id': 1}; var b = a; b = {'id': 2}; console.log(a.id); // 1 /* b는 {'id': 2} 라는 새로운 객체를 가리키게 되므로 a와 b는 각자 다른 객체를 참조하게 된다 */
-함수에서 원시 데이터 타입을 인자로 넘긴 경우, 위의 할당연산의 경우처럼 값이 복제 전달된다.
var a = 1; function func(b){ b = 2; } func(a); console.log(a); // 1 /* 위 예제는 * a = 1 * b = a * b = 2 인 경우와 같다*/
-함수에서 참조 데이터 타입을 인자로 넘긴 경우, 위의 할당연산의 경우처럼 값이 참조 전달된다.
var a = {'id': 1}; function func(b){ b.id = 2; } func(a); console.log(a.id); // 2 /* 위 예제는 * var a = {'id': 1}; * var b = a; * b.id = 2; 와 같다 */
'생활코딩 > ' 카테고리의 다른 글
[JS] 탬플릿 리터럴(`를 이용한 표현식) (0) 2020.09.09 [JS] 객체 지향 - 생성자와 new, 전역객체, this, 상속, prototype (0) 2020.09.05 [JS] 함수 - 유효범위, 콜백, 클로저, arguments, 호출 (0) 2020.09.03 [JS] 개요 - 함수, 배열, 객체, 모듈, Reference 참조, 정규식 (0) 2020.09.01 [JS] 개요 - 숫자와 문자열, 변수, 비교연산자, 조건문, 반복문 (0) 2020.08.31