객체와 배열, 함수의 기초

YangJiWon·2020년 8월 18일
0

모던 자바스크립트 입문 책을 정리한 내용입니다.

객체

  • 객체는 이름과 값을 한 쌍으로 묶은 데이터를 여러 개 모은 것입니다. 즉, 객체는 데이터 여러 개를 하나로 모은 복합 데이터로 연관 배열 또는 사전이라고도 부릅니다.
이름
suit"하트"
rank"A"
  • 객체에 포함된 데이터 하나(이름과 값의 쌍)를 가리켜 객체의 프로퍼티라고 부릅니다.
  • suit와 rank는 프로퍼티이며 프로퍼티의 이름 부분을 프로퍼티 이름 또는 라고 부릅니다.
  • 객체를 생성하는 방법은 두 가지로, 하나는 객체 리터럴, 다른 하나는 생성자를 사용하는 방법입니다.

객체 리터럴로 객체 생성

var card = { suit: "하트", rank : "A"};
card.suit // -> 하트 
card["rank"] // -> A
card.color // -> undefined
var obj = {};
console.log(obj); // -> Object{}

프로퍼티 추가와 삭제

  • 없는 프로퍼티 이름에 값을 대입하면 새로운 프로퍼티가 추가됩니다.
card.value = 14;
console.log(card); // -> Object {suit: "하트", rank: "A", value: 14}
  • delete 연산자를 사용하면 프로퍼티를 삭제할 수 있습니다.
delete card.rank;
delete card.suit;
console.log(card); //  -> Object {value: 14}
  • 이처럼 자바스크립트의 객체는 실행 중에 프로퍼티를 자유롭게 추가하거나 삭제할 수 있습니다.

in 연산자로 프로퍼티가 있는지 확인

프로퍼티 이름을 뜻하는 문자열 in 객체명

var card = {suit: "heart"};
console.log("suit" in card); // -> true
console.log("color" in card); // -> false
  • in 연산자가 조사하는 대상이 그 객체가 가진 프로퍼티와 그 객체가 상속받은 모든 프로퍼티라는 점을 주의하세요.

메서드

프로퍼티에 저장된 값의 타입이 함수이면 그 프로퍼티를 메서드라고 부릅니다.

객체는 참조 타입

  • 생성된 객체는 메모리의 영역을 차지하는 한 덩어리가 됩니다. 객체 타입의 값을 변수에 대입하면 그 변수에는 객체의 참조(메모리의 위치 정보)가 저장됩니다.

함수

수학에서는 함수는 주어진 입력 x에 대해 출력 y를 대응시키는 규칙입니다.

함수 선언문으로 함수 정의

function square(x) { return x * x; }

return문 다음에는 줄 바꿈 문자를 넣지 말아야 합니다.
return
x / x;
이렇게 작성하면 자바스크립트 엔진은 이 코드를 다음과 같이 해석합니다.
return;
x / x;
즉, 값이 없는 return 문으로 해석합니다.

함수 선언문의 끌어올림(호이스팅)

  • 자바스크립트 엔진은 변수 선언문과 마찬가지로 함수 선언문을 프로그램의 첫머리로 끌어올립니다.
console.log(square(5)); // -> 25
function square(x) { retrun x * x; }

함수 참조에 의한 호출과 값에 의한 호출

  • 함수는 원시 값을 인수로 넘겼을 때와 객체를 인수로 넘겼을 때 다르게 동작합니다.
function add1(x) { return x = x + 1; }
var a = 3;
var b = add1(a);
console.log("a = " + a + ", b = " + b); // -> a = 3, b = 4

add1은 전달받은 인수에 1을 더하여 반환하는 함수입니다. 이 함수가 호출될 때 변수 a의 복사본이 인자 x에 할당됩니다. 즉, 인수에 원시 값을 넘기면 그 값 복사를 실행합니다.
이 때 변수 a와 변수 x는 다른 영역의 메모리에 위치한 별개의 변수입니다.

function add1(p) {p.x = p.x + 1; p.y = p.y + 1; return p; }
var a = {x:3, y:4}
var b = add1(a);
console.log(a, b); // Object{x=4, y=5} Object{x=4, y=5}

인수로 객체를 넘겼을 때는 전달되는 값은 참조 값입니다.
이 때 p와 a는 똑같은 객체를 참조하고 있습니다.

인수 여러 개를 우아하게 전달하기


function setBallProperties(x, y, vx, vy, radius) {
  ... 
}
setBallProperties(0, 0, 10, 15, 5);

//------------------
function setBallProperties2(params) { 
  ... 
}
var parameters = {
  x : 0,
  y : 0,
  vx : 10,
  vy : 15,
  radius : 5,
  color : "blue"
};

setBallProperties2(parameters);
                                     
  • 함수 안에서 객체의 프로퍼티를 수정하면 호출한 코드에 인수 객체의 프로퍼티가 함께 바뀌므로 주의해야 합니다.

함수 안에서의 변수 선언과 변수 끌어올림(호이스팅)

  • 함수 안에서 선언된 지역 변수의 유효 범위는 함수 전체입니다. 함수 중간 부분에서 변수를 선언하더라도 변수는 함수 첫머리에서 선언된 것처럼 함수 안의 다른 문장보다 먼저 생성됩니다. 즉, 자바스크립트 엔진은 함수 안의 변수 선언부를 함수의 첫머리로 끌어올립니다.
function f() {
	console.log(a); // -> undefined
    var a = "local";
    console.log(a); // -> local
    return a;
}

let과 const

let

  • let 문은 블록 유효 범위를 갖는 지역 변수를 선업합니다.
  • var로 선언한 변수와 let으로 선언한 변수의 가장 큰 차이점은 let으로 선언한 변수의 유효범위가 블록 안이라는 점입니다.
  • let으로 선언한 변수는 호이스팅이 되지 않습니다.
  • 또한 let문으로 똑같은 이름을 가진 변수를 선언하면 문법 오류가 발생합니다.

const

  • const 문은 블록 유효 범위를 가지면서 한 번만 할당할 수 있는 변수(상수)를 선언합니다. const로 선언한 상수는 let 문으로 선언한 변수처럼 동작합니다. 단, 반드시 초기화해야 한다는 차이점이 있습니다.

함수를 활용하면 얻을 수 있는 장점

  1. 재사용할 수 있다
  2. 만든 프로그램을 이해하기 쉽다.
  3. 프로그램 수정이 간단해진다.

생성자

생성자로 객체 생성하기

function Card(suit, rank) {
	this.suit = suit;
    this.rank = rank;
}
var card = new Card("하트", "A");
console.log(card); // -> Card {suit : "하트", rank : "A"}
  • 생성자로 객체를 생성할 때는 new 연산자를 사용합니다.
  • new 연산자로 객체를 생성할 것이라 기대하고 만든 함수를 생성자라고 부릅니다.
  • 생성자 이름은 관례적으로 그것이 생성자임을 알리기 위해 첫 글자를 대문자로 쓰는 파스칼 표기법을 사용합니다.
  • 생성자와 new 연산자로 생성한 객체를 그 생성자의 인스턴스라고 부릅니다.
  • 생성자는 객체를 생성하고 초기화하는 역할을 합니다.

메서드를 가진 객체를 생성하는 생성자

function Circle(center, radius) {
  this.center = center;
  this.radius = radius;
  this.area = function() {
    return Math.PI * this.radius * this.radius;
  };
}
var p = {x:0, y:0};
var c = new Circle(p, 2.0);
console.log("넓이 = " + c.area());

자바스크립트 객체의 분류

네이티브 객체

  • ECMAScript 사양에 정의된 객체가 네이티브 객체입니다. 내장 생성자(Object, String, Number, Boolean, Array, Function 등)로 생성된 객체와 JSON, Math, Reflect 등이 네이티브 객체입니다.

호스트 객체

  • ECMAScript에는 정의되어 있지 않지만 자바스크립트 실행 환경에 정의된 객체가 호스트 객체입니다. 브라우저 객체(Window, Navigator, History, Location 등), DOM에 정의되어 있는 객체, Ajax를 위한 XMLHttpRequest 객체, HTML5의 각종 API 등이 클라이언트 측 자바스크립트에 정의된 호스트 객체의 예입니다.

사용자 정의 객체

  • 사용자가 정의한 자바스크립트 코드를 실행한 결과로 생성된 객체가 사용자 정의 객체입니다.

배열

배열 리터럴로 생성하기

var evens = [2, 4, 6, 8];
  • 앞 코드에서 [...] 부분이 배열 리터럴이며 배열 값 하나를 배열 요소라고 부릅ㄴ디ㅏ.

length 프로퍼티

var evens = [2, 4, 6, 8];
evens.length // => 4
  • 배열의 length 프로퍼티에는 배열 요소의 최대 인덱스 값 + 1이 담겨 있습니다.
  • 자바스크립트에서는 length가 배열 요소의 개수를 뜻하지 않는 경우가 있으므로 주의해야 합니다.

배열 Array 생성자로 생성하기

var evens = new Array(2, 4, 6, 8);
var empty = new Array();
var various = new Array(3.14, "pi", true, {x:1, y:2}, [2, 4, 6, 8]);
  • Array 생성자의 인수가 한 개고 그 값이 양의 정수면 의미가 달라집니다. 이 때 인수는 배열 길이를 뜻하므로 배열이 그 길이만큼 생성됩니다.
var x = new Array(3);
console.log(x.length); // -> 3
  • 반면 Array 생성자의 인수가 한 개고 그 값이 양의 정수가 아니면 오류가 발생합니다.
var x = new Array(-3);

배열은 객체

  • C나 Java 같은 프로그래밍 언어의 배열 요소는 메모리의 연속된 공간에 차례대로 배치되어 있습니다. 따라서 인데스를 지정하면 인덱스가 가리키는 요소를 매우 빠르게 읽거나 쓸 수 있습니다.
  • 그러나 자바스크립트의 배열은 다릅니다. 자바스크립트의 배열은 Array 객체이며 객체로 배열의 기능을 가상으로 흉내 낸 것입니다.
  • Array 객체는 배열의 인덱스를 문자열로 변환해서 그것을 프로퍼티로 이용합니다. 즉, 배열에 대괄호 연산자를 사용하는 것은 객체에 대괄호 연산자를 사용하는 것과 마찬가지이며, 배열의 요소 번호로 숫자 값 대신 문자열을 사용할 수 있습니다.
var a = ["A"]
console.log(a["0"]) // -> A
a[2] // -> undefined
  • ECMAScript 6부터는 TypedArray 객체가 추가되었습니다. TypedArray의 배열 요소는 C나 Java 등의 배열과 마찬가지로 메모리의 연속된 공간에 차례대로 배치됩니다.

배열 요소의 추가와 삭제

var a = [1, 2, 3];
a.push(4);
console.log(a); // -> [1, 2, 3, 4]
delete a[0];
console.log(a); // -> [undefined, 2, 3, 4]
  • delete 연산자를 사용하여 배열의 요소를 삭제해도 그 배열의 length 프로퍼티 값은 바뀌지 않습니다. 즉, 삭제한 요소만 사라집니다.

희소 배열

  • 배열에 요소를 추가하거나 제거하면 인덱스가 0부터 시작되지 않는 배열
var a = [1, 2, 3];
a[4] = 5;
console.log(a); // -> [1, 2, 3, undefined, 5];

배열 요소가 있는지 확인하기

배열 요소가 있는지 확인하는 방법은 객체의 프로퍼티가 있는지 확인하는 방법과 같습니다.
for/in 문이나 hasOwnProperty 메서드를 사용해서 확인할 수 있습니다.

var a = [0, 1, 2, undefined, 4];
for (var i of a) console.log(i); // 0, 1, 2, 4가 표시됨
a.hasOwnProperty("3");	// -> false
a.hasOwnProperty("4");	// -> true
profile
데이터데이터데이터!!

0개의 댓글