34
JavaScript 2015.07.10 작성자 : 홍효상 작성자 : 홍효상

Javascript 교육자료 pdf

  • Upload
    -

  • View
    139

  • Download
    7

Embed Size (px)

Citation preview

JavaScript

2015.07.10

작성자 : 홍효상작성자 : 홍효상

Content

1 Javascript ?

2 객체

3 함수

4 This

5 Scope & Hosting & Closeure

6 argement 객체6 argement 객체

7 Array

8 Type

9 Object Prototype

참조 사이트

http://unschooled.org

http://html5experts.kr

http://bonsaiden.github.io/JavaScript-Garden/

JavaScript

브라우저 자체에 내장된 해석 기능을 이용한 클라이언트 기반의 객체 지향 스크립트 언어.

동적인 웹 페이지를 작성하기 위해서 사용 되는 언어.

1. JavaScript 란

1. JavaScript ?

1-1. 용도

• 이벤트에 반응 하는 동작 구현

• 서버에서 정보를 받거나 정보를 전달 하기 위해 사용

• HTML 요소들의 크기나 색상을 동적으로 변경

• 대화형 컨텐츠 구현

• 사용자의 입력 검증

1-2. 표현식 과 문장

Copyright©2015 ABACUS, Co. All rights reserved. 2

1-2. 표현식 과 문장

• 표현식 : JavaScript에서 값을 만들어내는 간단한 코드

• 문장 : 하나 이상의 표현식 모임

• 문장의 끝은 세미콜론(;)으로 종결자 표시를 한다.

1-3. 식별자

• 의미 있는 단어를 사용 하여 변수와 함수명을 만든다.

• 키워드(true, case, if ..) 등으로 함수 또는 변수명을 사용 하지 말아야 한다.

• 숫자 또는 특수 문자 (“_”, “$” 제외)로 시작 하면 안됨

• 공백 문자를 포함 할 수 없음

JavaScript

1. JavaScript ?

1-4. 변수 선언

• 숫자나 문자열과 같은 단순한 데이터 형식, 객체, 복잡한 데이터 형식을 담는다.

• var 로 선언을 하면 선언과 동시에 초기화 할 수 있다.

1-5. 데이터 형식

• 자바 스크립트에서 변수 형식은 해당 변수가 어떤 작업을 수행 하는지를 결정 한다.

• 문자열 : 문자 데이터를 문자열로 저장, 작은 따옴표 또는 큰 따옴표로 명시

• 숫자 : 숫자를 나타내는 값을 데이터로 저장

• 불린 : true, false를 뜻하는 단일 비트 저장

var myString ;myString = ‘홍길동’;

var myString, myName;var myString = ‘홍길동’; myNmae = '홍길동';myString = '미미';console.log(myString); console.log(myNmae);

Copyright©2015 ABACUS, Co. All rights reserved. 3

• 불린 : true, false를 뜻하는 단일 비트 저장

• 배열 : 분리 구분된 일련의 데이터 요소들로 모두 하나의 변수명으로 저장

- 0부터 시작 하는 인텍스를 이용 해서 array[index]를 사용

• 객체리터럴 : key, value로 정의 되어 있는 데이터로 object.property로 접근 할 수 있음

• null : null

var myString = '문자';var myNuber = 1;var myBoolean = true;var myArray = ['a','b','c'];var myObject = {"name":"홍길동", "age":"19"};var myNull = null; // ? var myNull = “null”;console.log(typeof myString, myString); // string 문자console.log(typeof myBoolean, myBoolean); // boolean trueconsole.log(typeof myArray, myArray, myArray[0]); // object [ 'a', 'b', 'c' ] aconsole.log(typeof myObject, myObject, myObject["name"]); // object { name: '홍길동', age: '19' } 홍길동console.log(typeof myNull, myNull); // object null

JavaScript

1. JavaScript ?

1-6. 산술 연산자

1-7. 비교(조건) 연산자

1-8. 대입 연산자

1-9. if, switch, while, do/while, for, for/in

• +, -, ++, --,*, /, %

• ==(값만 같음), === ( 값과 형식이 모두 같음 ), !=, !===, > , >=, <, <=, &&, ||, !

• =, +=, -=, *=, /=, %=

if (조건) {만족;

switch(수식) {case 값:

while (조건) {조건이 false일때 까지

for( 대입문; 조건문; 갱신문) {…..

Copyright©2015 ABACUS, Co. All rights reserved. 4

만족;} else {

불만족}

case 값:<실행코드>;break;

case 값1:<실행코드>break;

default :<값, 값1도 아닌 경우>

}

do {적어도 한번 실행

} while (조건)

조건이 false일때 까지}

…..}

. continue, break

반복 될 수 있는 모든 데이터형식을 대상으로 ,,,var myArray = ['a','b','c'];for (var idx in myArray) {

console.log(myArray[idx]);}

JavaScript

JavaScript는 null과 undefined를 제외한 모든 것들은 객체처럼 동작

name/value 쌍으로 된 Property로 구성 되기 때문에 Hashmap 처럼 사용 될 수 있음

{}로를 이용 해서 생성을 하며 속성 값에 접근 할 떄 키로 접근

2. 객체

2. 객체

2-1. Property와 Method

Property : 객체 내부에 있는 값으로 JavaScript에서 제공 하는 모든 자료형을 가질 수 있음

Method : 함수 자료형인 속성으로 자기 자신의 속성이라는 것을 표시 할 떄는 this keyword로 표현

2-2. For in 반복문

객체의 속성을 사용 하기 위해서 for in 반복문을 사용

Copyright©2015 ABACUS, Co. All rights reserved. 5

모두 객체 이다false.toString(); // ‘false’[1,2,3,4].toString(); // ‘1,2,3,4’function fun() {};fun.count = 1;fun.count; // 1

2.toString(); // syntaxError-> 2.2.toString();-> 2 .toString();-> (2).toString();

2-3. 예

객체 생성 방법1) 빈 객체 생성 : var fun = {}; 2) Property 가 있는 객체 생성

var fun = {name:’함수명’}

접근 방법1) 직접접근 : fun.mame; 2) 문자로접근 : fun[‘name’];3) 변수로 접근

var get = ‘name’;fun[get]

1),2),3) 모두 ‘함수명’을 의미함

property 삭제1) delete 사용

var nameObj = { first:1, middle:2, last:3};nameObj.first = ‘홍’;nameObj.middle = ‘길동’delete nameObj.last;

for ( var i in name ) {if ( name.hasOwnPropwrty(i) {

console.log(I, ‘’ + name[i];}

}

JavaScript

2-4. 객체리터럴표기법

2. 객체

생성한 객체는 언제라도 변경 가능 하며, 내장 네이티브 객체의 프로퍼티도 대부분 변경이 가능 하다.

이처럼 필요에 따라 객체 생성 할 때 이상적임

//1. 빈 객체를 선언 한다.//2. 프로퍼티를 하나 추가 한다.//3. 메소드를 하나 추가 한다.var person = {};person.name = '홍길동';person.getName = function() {

return person.name;};//4. 재정의 이전console.log(person.getName()); // 홍길동

var person = {name : '홍길동',getName : function () {

return this.name;}

};

console.log(person.getName()); // 홍길동person.name = ‘홍당무';

Copyright©2015 ABACUS, Co. All rights reserved. 6

console.log(person.getName()); // 홍길동person.getName = function() {

return '홍당무';};//4. 재정의 이후console.log(person.name); // 홍길동console.log(person.getName()); // 홍당무

person.name = ‘홍당무';console.log(person.getName()); // 홍당무

객체 생성시 new 연산자를 사용 하지 마라-> 생성자에 파라메터로 전달시 해당 값의 형으로 결정 되므로

var person = new Object();console.log(person.constructor === Object); // true

var person = new Object(1);console.log(person.constructor === Object); // falseconsole.log(person.constructor === Number); // true

JavaScript

2-5. 베열 리터럴

2. 객체

var a = new Array("1","2","3");console.log(typeof a); // 배열도 객체 이므로 objectconsole.log(a.constructor); // [Function: Array]

var b = ["1","2","3"];console.log(typeof b); // 배열도 객체 이므로 objectconsole.log(b.constructor); // [Function: Array]

var aa = new Array(3);console.log(aa.length); // 3console.log(aa[0]); // undefined

Copyright©2015 ABACUS, Co. All rights reserved. 7

console.log(aa[0]); // undefined

var bb = [3];console.log(bb.length); // 1console.log(bb[0]); // 3

JavaScript

3. 함수

3-1. First Class Object

JavaScript는 함수 자체가 다른 함수의 인자가 될 수 있다. 즉 First Class Object

함수는 변수우ㅏ 스코프를 결정 하고 private변수 또는 메소드 뿐만 아니라 함수의 특징을 이용 하여 public 속성과 메소드를

제공 하며 자바 스크립트 모듈을 작성 한다.

변수애 저장 할 수 있어야 한다.

함수를 파라메터로 전달할 수 있어야 한다.

함수의 반환값으로 사용할 수 있어여 한다.

자료 주조에 저장할 수 있어여 한다.

3-2. 함수와 익명 함수

함수를 정의 하는 방법함수 선언식으로 표현 하면 로딩 시점에 에

Copyright©2015 ABACUS, Co. All rights reserved. 8

함수를 정의 하는 방법

- Function 객체를 사용 하는 방법

- 연산자인 Function을 사용 하는 방법

-> 함수 선언문 ( Function Declaration )

-> 함수 표현식 ( Function Expression )

함수 선언 방법 예제

함수 선언식 (Function Declaration) function fun() { … }

기명 함수 표현식 (Named Function Expression) var fun = function fun() { … }

익명 함수 표현식 (Anonymous Function Expression) var fun = function() { … }

기명 즉시실행함수(named immediately-invoked function expression) (function fun() { …} ());

익명 즉시실행함수(immediately-invoked function expression) (function() { … })();

함수 선언식으로 표현 하면 로딩 시점에 VO(Variable Object)에

적재 하므로 오느 곳에서도 접근 가능.

함수 표현식으로 표현 하면 Runtime시점에 적재

-> 규모가 큰 프로젝트 인 경우 고려 사항

JavaScript

3. 함수

3-2-1. 함수표현식에의한 함수 호출과 즉시 실행 함수호출

var func = function() {

console.log(‘함수 표현식에 의한 명시적인 호출’);

};

func();

(function() {

console.log(‘즉시 실행 함수’);

}());

3-2-2. 변수에즉시실행 함수를 할당후 실행

var app = (function() {

var name = ‘홍길동’;

return {

pNmae : name

};

결과 : 홍길동

** 함수 내부에 선언한 변수에 대한 접근 가능

Copyright©2015 ABACUS, Co. All rights reserved. 9

};

}

Console.log(app.pName);

3-2-3. 기명 함수 사용

var fPrintName= function(name) {

concole.log(‘나의 이름음 ‘+ name + ‘이다’);

};

fPrintName(‘홍길동’);

(function(name) {

concole.log(‘나의 이름음 ‘+ name + ‘이다’);

}(‘홍길동’));

묘듈화된 방법으로 작성을 할 수 있다.

JavaScript

3. 함수

3-2-3. 익명함수이용한 scope영역 관리

var fGetName= {

firstName: function() {

alert(‘홍’);

},

fullName: function(){

alert(‘홀길동’);

}

}

fGetName.firstName();

fGetName.fullName();

3-2-4. 생성자

Copyright©2015 ABACUS, Co. All rights reserved. 10

3-2-4. 생성자

• new 키워드로 호출되는 함수가 생성자

• 생성자로 호출된 함수의 this 객체는 새로 생성된 객체를 가리키고, 새로 만든 객체의 prototype 에는 생성자의 prototype이 할당된다

• 전역범위는 전채를 위미 하며 지역 범위는 정의 된 함 수 내에서만 참조 되는 것을 의미 함

• 생성자에 명시적인 return 구문이 없으면 this가 가리키는 객체를 반환한다

function Person(name) {this.name = name;

}

Person.prototype.logName = function() {console.log(this.name);

};

var sean = new Person();

JavaScript

3. 함수

• 생성자에 명시적인 return 문이 있는 경우에는 반환하는 값이 객체인 경우에만 그 값을 반환한다.

function car() {return 'ford';

}console.log(car()); // fordconsole.log(new car()); // 'ford'가 아닌 새로운 객체를 반환 --> {}

function person() {this.someValue = 2;return {

name: 'Charles'};

}console.log(person()); // { name: 'Charles' }

Copyright©2015 ABACUS, Co. All rights reserved. 11

console.log(person()); // { name: 'Charles' }console.log(new person()); // { name: 'Charles' }

• new 키워드가 없으면 그 함수는 객체를 반환하지 않는다

function Pirate() {this.hasEyePatch = true; // 전역 객체를 준비!

}

var somePirate = Pirate(); // somePirate = undefined

console.log(somePirate); // undefinedconsole.log(hasEyePatch); // true

//console.log(somePirate.hasEyePatch); // Cannot read property 'hasEyePatch' of undefined

JavaScript

4. This

4. this

• 전역 객체를 참조 ( Global Scope)

• 메소드 내부의 this는 해당 메소드를 호출한 부모 객체를 참조

• 생성자 함수 코드 내부의 this는 새로 생성된 객체를 참조.

• call()과 apply() 메소드로 함수를 호출할 때, 함수의 this는 첫 번째 인자로 넘겨받은 객체를 참조

• 프로토타입 객체 메소드 내부의 this도 해당 메소드를 호출한 부모 객체를 참조.

• JavaScript의 this 키워드는 접근제어자 public 역할

JavaScript의 this는 해당 함수 호출 패턴에 따라서 의미가 다르다.

4-1. Global Scope

•JavaScript의 모든 전역 변수는 실제로 전역 객체(브라우저에서는 window객체)의 프로퍼티들입니다. 모든 프로그램은 global code의

Copyright©2015 ABACUS, Co. All rights reserved. 12

•JavaScript의 모든 전역 변수는 실제로 전역 객체(브라우저에서는 window객체)의 프로퍼티들입니다. 모든 프로그램은 global code의실행에 의해서 시작하고 this는 정해진 실행 문맥의 안에 고정되기 때문에 JavaScript의 this는 global code의 전역 객체입니다.

4-2. 부모 객체 참조

var counter = {

val: 0,

increment: function() {

this.val += 1;

}

};

counter.increment();

console.log(counter.val); // 1

counter['increment']();

console.log(counter.val); // 2

varValue = 100;

var counter = {

varValue: 0,

increment: function() {

console.log(this);

this.varValue += 1;

}

};

var inc = counter.increment;

inc();

console.log(counter.varValue);// 0

console.log(varValue); // 101

Count객체가 increment메소드를부모 객체 호출

-> this의 범위는 자신을 호출 한

객체 참조

Inc 전역변수에 counter.increment할당 함으로 전역 화됨

-> 첫번째 계산은 100 + 1

varValue = 100;을 var로 선언 하였을때는 ?

JavaScript

4. This

4-2. 부모 객체 참조

val = 100;

var counter = {

val: 1,

func1: function() {

//console.log(this); // { val: 1, func1: [Function] }

this.val += 1;

console.log('func1() this.val: '+ this.val); // func1() this.val: 2

func2 = function() {

console.log(this);

// 부모를 의미함 -> root val: 100, func2: [Function]

this.val += 1;

console.log('func2() this.val: '+ this.val); // func2() this.val: 101

func3 = function() {

var val = 100;

var counter = {

val: 1,

func1: function() {

var that = this; // -> { val: 1, func1: [Function] }

this.val += 1;

console.log('func1() this.val: '+ this.val); // func1() this.val: 2

func2 = function() {

console.log(that); // > { val: 2, func1: [Function] }

that.val += 1;

console.log('func2() that.val: '+ that.val); // func2() that.val: 3

func3 = function() {

that.val += 1;

Copyright©2015 ABACUS, Co. All rights reserved. 13

func3 = function() {

this.val += 1;

console.log('func3() this.val: '+ this.val); // func3() this.val: 102

}

func3();

}

func2();

}

};

counter.func1();

console.log('func3() that.val: '+ that.val); // func3() that.val: 4

}

func3();

}

func2();

}

};

counter.func1();

JavaScript에서는 내부 함수 호출 패턴을 정의해 놓지 않기 때문

-> 내부 함수도 결국 함수이므로 이를 호출할 때는 함수 호출로 취급 됨

-> 함수 호출 패턴 규칙에 따라 내부 함수의 this는 전역 객체를 참조

-> func1(메소드)에서는 메소드 내부의 val 값이 출력, func2(내부 함수), func3(내부 함수)에서는 전역 변수의 val 값이 출력

JavaScript

4. This

4-3. 생성자 함수 호출

function F(v) {

console.log(this); // {}

this.val = v;

}

var f = new F("constructor function");

console.log(f); // { val: 'constructor function' }

console.log(f.val); // constructor function

• 생성자 함수를 호출할 때, 생성자 함수 코드 내부의 this는 새로 생성된 객체를 참조

function F(v) {

console.log(this); // 부모의미

this.val = v;

}

var f = F("constructor function");

console.log(val); // constructor function

// console.log(f.val); Uncaught TypeError: Cannot read property 'val' of undefined

This 전역 객체 참조 되므로

4-4. call과 apply Method 함수호출

Copyright©2015 ABACUS, Co. All rights reserved. 14

4-4. call과 apply Method 함수호출

• JavaScript에는 이러한 내부적인 this 바인딩 이외에도 this를 특정 객체에 명시적으로 바인딩 시키는 apply()와 call() 메소드 제공.

• apply()과 call() 메소드로 함수를 호출할 때, 함수는 첫 번째 인자로 넘겨받은 객체를 this로 바인딩하고, 두 번째 인자로 넘긴 값들은 함수의 인자로 전달.

• apply() 메소드는 배열 형태로 인자를 넘기고, call() 메소드는 배열 형태로 넘긴 것을 각각 하나의 인자로 넘기는 것입니다.

var add = function(x, y) {

//console.log(this.val); // 첫번재 apply에서 호출 되는 경우 0으로 초기화 함 : obj에 val이 정의 되어 있으므로

this.val = x + y; this.val += this.hval;

};

var obj = {

val: 0, hval : 10

};

add.apply(obj, [2, 8]);

console.log(obj.val); // 10

add.call(obj, 2, 8);

console.log(obj.val); // 10

첫번쟤 인자로 obect를 넘김

JavaScript

4. This

4-5. 프로토타입 객체메소드의 this로 해당매소드호출

• 프로토타입 객체는 메소드를 가질 수 있다.

• 이 프로토타입 메소드 내부에서의 this도 똑같이 메소드 내부의 this는 해당 메소드를 호출한 부모 객체를 참조.

function Person(name) {

this.name = name;

}

Person.prototype.getName = function() {

return this.name;

}

thisnew Person {} name에 할당 { name: 'foo' }foo.getName { getName: [Function], name: 'foo ' }Person.prototype.name { getName: [Function], name: person' }

Copyright©2015 ABACUS, Co. All rights reserved. 15

var foo = new Person('foo');

console.log(foo.getName()); // foo

// -> getName() 메소드는 foo 객체에서 찾을 수 없으므로 프로토타입 체이닝이 발생

// -> foo 객체의 프로토타입 객체인 person.prototytpe에서 getName() 메소드가 있으므로, 이 메소드가 호출

// -> getName() 메소드를 호출한 객체는 foo이므로, this는 foo 객체에 바인딩

// -> foo.getName()의 결과로 foo가 출력

Person.prototype.name = 'person';

console.log(Person.prototype.getName()); // person

JavaScript

4. This

4-5. Public 역활

• public, private 키워드 자체를 지원하지 않지만 public 역할을 하는 this 키워드와 private 역할을 하는 var 키워드가 있습니다. JavaScript에서는 이 두 키워드를 사용하여 캡슐화

function Person(name, age) {

var Name = name;

this.Age = age;

this.getName = function() {

return Name;

}

}

var foo = new Person('foo', 26);

Copyright©2015 ABACUS, Co. All rights reserved. 16

var foo = new Person('foo', 26);

console.log(foo.Age); // 26

console.log(foo.Name); // undefined

console.log(foo.getName()); // foo

this키워드로 선언된 Age에는 접근할 수 있지만

var 키워드로 선언된 Name에는 접근할 수 없음 var 키워드로 선언된 변수는 외부에서 확인할 수 없으므로 undefined로 출력

JavaScript

4. This

4-6. 대표적인함정

var Foo = {};

Foo.method = function() {var self = this;function test() {console.log(self);

// 여기에서 this 대신에 self를// 사용하여 Foo에 접근한다

}test() ;

}Foo.method();

var Foo = {val : 'hong'

};

Foo.method = function() {var test = function() {

console.log(this);console.log(this.val);

// this는 이제 Foo를 참조한다}.bind(this);test() ;

}Foo.method();

var Foo = {};

Foo.method = function() {function test() {console.log(this);// 여기에서 this는 Global // 객체를 가리킨다

}test();

}Foo.method();

test 에서 this가 Foo를 가리킬 것으로

Copyright©2015 ABACUS, Co. All rights reserved. 17

self는 통상적인 변수 이름이지만, 바깥쪽의this를 참조하기 위해 일반적으로 사용된다. 또한 클로저와 결합하여 this의 값을 주고받는 용도로 사용할 수도 있다

Foo.method();

ECMAScript 5부터는 익명 함수와 결합된bind 메써드를 사용하여 같은 결과를얻을 수 있다.

test 에서 this가 Foo를 가리킬 것으로생각할 테지만 틀렸다. 실제로는그렇지 않다.test에서 Foo에 접근하려면 method에Local 변수를 하나 만들고 Foo를가리키게 하여야 한다

* 프로토 타입 상속 ( prototypal ingeritance )function Foo() {};Foo.prototype.method = function() {

console.log("이건 뭐야 ...");};function Bar() {}Bar.prototype = Foo.prototype;new Bar().method();

Bar 인스턴스에서 method를 호출하면 method에서this는 바로 그 인스턴스를 가리킨다.

JavaScript

5. Scope & Hositing & Closure

5-1. Scope

• 변수와 매개변수의 접근성과 생존 시간을 의미 함

• 전역범위(Global Scope)와 지역 유효 범위(Local Scope)로 나뉜다.

• 전역범위는 전채를 위미 하며 지역 범위는 정의 된 함 수 내에서만 참조 되는 것을 의미 함

var gVari= ‘global’;

function funcA() {

var laVar = ‘function Local FuncA ’;

function funcB() {

var lbVar = ‘function Local FuncB’;

}

}

gVal : Global Scope

laVal : Local Scope : funcA 안에서lbVal : Local Scope : funcB 안에서

var 키워드의 생략 렉시컬 특성

Copyright©2015 ABACUS, Co. All rights reserved. 18

함수 단위의 유효범위function fscopeTest() {

var a = 0;if (true) {

var b = 0;for (var c = 0; c < 5; c++) {

console.log("c=" + c);}console.log("c=" + c);

}console.log("b=" + b);

}fscopeTest();

변수명 중복 허용var gVar= 10;function fDupVar(){

var gVar= 20;console.log(“gVar= " +scope);

}fDupVar();

var 키워드의 생략function fNoDefVar(){

gVar= 20;console.log(" gVar = " + gVar);

}

function fNoDefVar2(){console.log(" gVar = " + gVar);

}fNoDefVar();fNoDefVar2();

렉시컬 특성function f1(){

var a= 10;f2();

}function f2(){

return console.log("호출 ");}F1();function f1(){

var a= 10;f2();

}function f2(){

return a;}f1();

JavaScript

5. Scope & Hoisting & Closure

5-2. 호이스팅(Hoisting)

• 모든 변수는 함수 본문 어느 부분에서 선언 되더라도 내부적으로 함수의 맨 윗부분으로 끌어올려진다.

• 함수도 변수에 할당 되는 객체이기 때문에 동일하게 적용이 된다.

변수 hoistingconsole.log("변수 " + a); // 변수 undefinedvar a = "1";console.log("변수 " + a); // 변수 1

함수 hoistingfunction foo() {console.log("gloabl foo----");}

함수 hoisting -> bar는 hoisting 되지만 정의된 함수는hoisting 되지 않는다.function foo() {console.log("gloabl foo----");}

function hoisting() {console.log(typeof foo); // functionconsole.log(typeof bar); // undefined

Copyright©2015 ABACUS, Co. All rights reserved. 19

}

function hoisting() {console.log(typeof foo); // functionconsole.log(typeof bar); // function

foo(); // gloabl foo----bar(); // gloabl bar----

};hoisting();

function bar() {console.log("gloabl bar----");

}

foo(); // local foo----bar(); // error : undefined is not a function

function foo() { // 재정이됨 -> 유효범위 체인console.log("local foo----");

};

var bar = function() {// 재정이됨 -> 유효범위 체인console.log("local bar----");

};

};hoisting();bar(); // gloabl bar----

function bar() {console.log("gloabl bar----");

}

JavaScript

5. Scope & Hositing & Closure

5-3. Closure

• JavaScript의 유효범위 체인을 이용하여 이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 방법

• 외부에서 내부 변수에 접근할 수 있도록 하는 함수입니다

• 클로저를 만들면 클로저 스코프 안에서 클로저를 만든 외부 스코프(Scope)에 항상 접근할 있다

5-3-1. 유효범위체인 ( Scope Chain )

• 함수가 중첩함수일 때 상위함수의 유효범위까지 흡수하는

• 하위함수가 실행되는 동안 참조하는 상위 함수의 변수 또는 함수의 메모리를 참조하는 것

function counter(start) {var count = start;return {increment: function() {

5-3-2. private 변수 만들기

• counter는 increment, get 두개의 Closure을 가지고 있음.

• 두개의 함수가 count를 참조 하고 있으므로 이 함수 Scope안에서는 count 변수를 계속 접근 할 수 있음

Copyright©2015 ABACUS, Co. All rights reserved. 20

increment: function() {count++;

},get: function() {

return count;}

};}

var foo = new counter(4);foo.increment();console.log(foo.get()); // 5foo.hack = function() {

count = 1337;};foo.hack();console.log(foo.get()); // 5console.log(count); // 1337

수를 계속 접근 할 수 있음

• hack 함수는 Counter 함수에 정의 가 되어 있지 않아서 count에 설정을 하여도 count 값은 변경 되지 않는다. Hack에서 변경 한 count 는 Global 변수에 적용 됨

JavaScript

5. Scope & Hositing & Closure

for(var i = 0; i < 5; i++) {console.log("^^^^^^"); setTimeout(function() {

console.log(i); }, 1000);

}// 10만 열번 출력 됨-> 타이머에 설정된 익명 함수는 변수 i에 대한 참조를 들고

있다가 console.log가 호출되는 시점에 i의 값을 사용한다. console.log가 호출되는 시점에서 for loop는 이미 끝난상태기 때문에 i 값은 10이 된다

5-3-3. 반복문에서 Closure 사용하기

익명함수로 랩핑for(var i = 0; i < 10; i++) {

(function(e) {setTimeout(function() {

console.log(e); }, 1000);

})(i);} // 0,1,2,3,4,5,6,7,8,9

랩핑한 익명 함수에서 출력 함수를 반환하는 방법도for(var i = 0; i < 10; i++) {

setTimeout((function(e) {return function() {

Copyright©2015 ABACUS, Co. All rights reserved. 21

return function() {console.log(e);

}})(i), 1000)

}

setTimeout 함수에 세번째 인자를 추가하는 방법for(var i = 0; i < 10; i++) {

setTimeout(function(e) {console.log(e);

}, 1000, i);}

bind를 사용하는 방법for(var i = 0; i < 10; i++) {

setTimeout(console.log.bind(console, i), 1000);}

-성능문제 클로저가 필요하지 않는 부분에서클로저를 사용하는 것은 처리 속도와 메모리면에서 좋은 방법이 아닙니다

JavaScript

5. Scope & Hositing & Closure

5-3-4. Closure 오남용

• 함수 내부의 클로저 구현은 함수의 객체가 생성될 때마다 클로저가 생성되는 결과를 가져옵니다. 같은 구동을 하는 클로저가 객체마다 생성이 된다면 쓸데없이 메모리를 쓸데없이 차지하게 되는데, 이를 클로저의 오남용이라함 -> 성능 문제 ( 메모리)

function MyObject(inputname) {this.name = inputname;this.getName = function() {

return this.name;};this.setName = function(rename) {

this.name = rename;};

}var obj= new MyObject("서");console.log(obj.getName());

function MyObject(inputname) {this.name = inputname;

}MyObject.prototype.getName = function() {

return this.name;};MyObject.prototype.setName = function(rename) {

this.name = rename;};var obj= new MyObject("서");console.log(obj.getName());

prototype객체를 이용한클로저 생성

Copyright©2015 ABACUS, Co. All rights reserved. 22

var obj= new MyObject("서");console.log(obj.getName());

var obj= new MyObject("서");console.log(obj.getName());

5-3-5. Closure를 통해서는외부 함수의 this와 arguments객체를 참조할 수 없음

function f1(){function f2(){

console.log(arguments[0]);}return f2;

}var exam = f1(1);exam();

// undefined

function f1(){var a= arguments[0];function f2(){

console.log(a);}return f2;

}var exam = f1(1);exam();

// 1

JavaScript

5. Scope & Hositing & Closure

5-3-6. Closure을 이용한캡슐화

• 캡슐화란 간단하게 말하면 객체의 자료화 행위를 하나로 묶고, 실제 구현 내용을 외부에 감추는 겁니다. 즉, 외부에서 볼 때는 실제하는 것이 아닌 추상화 되어 보이게 하는 것으로 정보은닉

function Gugudan(dan){this.maxDan=3;this.calculate = function(){

for(var i =1; i<=this.maxDan; i++){console.log(dan+"*"+i+"="+dan*i);

}}this.setMaxDan = function(reset){

this.maxDan = reset;}

}

5*1=55*2=105*3=15

5*1=55*2=10

5*1=55*2=105*3=15

Copyright©2015 ABACUS, Co. All rights reserved. 23

}}var dan5 = new Gugudan(5);dan5.calculate();dan5.maxDan=2;dan5.calculate();dan5.setMaxDan(4);dan5.calculate();

5*3=155*4=20

JavaScript

6. argement 객체

6-1. argement 객체

• JavaScript의 모든 함수 스코프에는 arguments라는 특별한 변수가 있다. 이 변수는 함수에 넘겨진 모든 인자에 대한 정보가 담겨 있다

• arguments 객체는 Array가 아니다. 물론 length 프로퍼티도 있고 여러모로 Array와 비슷하게 생겼지만 Array.prototype을 상속받지는 않았다

• arguments에는 push, pop, slice 같은 표준 메소드가 없다.

•일반 for문을 이용해 순회는 할수 있지만, Array의 메소드를 이용하려면 arguments를 Array로 변환해야 한다.

• arguments 변수는 Function 안에서 다시 정의할 수 없다.

• var 구문이나 파라미터에 arguments라는 이름으로 변수를 정의해도 변수가 재정의되지 않는다.

function Person(first, last) {this.first = first;this.last = last;

}

Person.prototype.fullname = function( joiner, options) {

Copyright©2015 ABACUS, Co. All rights reserved. 24

Person.prototype.fullname = function( joiner, options) {options = options || { order: "western" };var first = options.order === "western" ? this.first : this.last;var last = options.order === "western" ? this.last : this.first;return first + ( joiner || " ") + last;

};

// "fullname" 메써드의 비결합(unbound) 버전을 생성한다. 첫번째 인자로 'first'와 'last' 속성을 가지고 있는 어떤 객체도 사용 가능하다.// "fullname"의 인자 개수나 순서가 변경되더라도 이 랩퍼를 변경할 필요는 없을 것이다.Person.fullname = function() {// 결과: Person.prototype.fullname.call(this, joiner, ..., argN);return Function.call.apply(Person.prototype.fullname, arguments);

};

var grace = new Person("Grace", "Hopper");console.log(grace.fullname()); // 'Grace Hopper'console.log(Person.fullname({ first: "Alan", last: "Turing" }, ", ", { order: "eastern" })); // 'Turing, Alan'

JavaScript

6. argement 객체

6-2. 일반 파라메터 와 argement객체의 인텍스

• 일반 파라메터와 arguments 객체의 프로퍼티는 모두 getter와 setter를 가진다.

• 파라메터나 arguments 객체의 프로퍼티의 값을 바꾸면 둘 다 바뀐다

function foo(a, b, c) {arguments[0] = 2;a; // 2

b = 4;arguments[1]; // 4

var d = c;d = 9;c; // 3

Copyright©2015 ABACUS, Co. All rights reserved. 25

c; // 3}foo(1, 2, 3);

arguments.callee와 arguments.callee의 프로퍼티들은 절대 사용하지 말자최신 JavaScript 엔진에서 arguments.callee를 사용하면 성능이 확 떨어진다.

// 자기 자신과 자신을 호출한 함수를 알아야 하기 때문에 더이상 인라인되지 않는다function foo() {

arguments.callee; // 이 함수를 가리킨다.arguments.callee.caller; // 이 함수를 호출한 부모함수를 가리킨다.

}

function bigLoop() {for(var i = 0; i < 100000; i++) {

foo(); // }}

JavaScript

7. Array

7-1. 배열 순회

• JavaScript에서는 배열(Array)도 객체(Object)지만 객체 순회(Iterate)를 할 때 for in을 사용해서 좋을 게 없다.

• for in은 프로토타입 체인에 있는 프로퍼티를 모두 훑는(enumerate) 데다가 객체 자신의 프로퍼티만 훑으려면 hasOwnProperty를 사용해야 하기 때문에 for보다 20배 느리다

7-2. 배열 생성자

• 배열을 만들때 배열 생성자에 파라미터를 넣어 만드는 방법은 헷갈릴수있다. 그래서 항상 각 괄호([]) 노테이션을 이용해 배열을 만들 것을권한다

var list = [1, 2, 3, 4, 5, ...... 100000000];for(var i = 0, l = list.length; i < l; i++) {

console.log(list[i]);}

var arr = [1, 2, 3, 4, 5, 6];arr.length = 3;arr; // [1, 2, 3]

arr.length = 6;

Copyright©2015 ABACUS, Co. All rights reserved. 26

}arr.length = 6;arr.push(4);arr; // [1, 2, 3, undefined, undefined, undefined, 4]

JavaScript

8. Type

8-1. 객체 비교 하기

• 이중 등호 연산자 ( == ) 는 다음과 같은 결과가 나므로 객체 비교 사용시 주의

"" == "0" // false0 == "" // true0 == "0" // truefalse == "false" // falsefalse == "0" // truefalse == undefined // falsefalse == null // falsenull == undefined // true" \t\r\n" == 0 // true

• 삼중 등호 연산자 ( === ) 는 삼중 등호는 강제로 타입을 변환하지 않는다는 사실을 제외하면 이중 등호와 동일하다

-> 삼중 등호를 사용하면 코드를 좀 더 튼튼하게 만들수 있고, 비교하는 두 객체의 타입이 다르면 더 좋은 성능을 얻을 수도 있다

Copyright©2015 ABACUS, Co. All rights reserved. 27

-> 삼중 등호를 사용하면 코드를 좀 더 튼튼하게 만들수 있고, 비교하는 두 객체의 타입이 다르면 더 좋은 성능을 얻을 수도 있다

"" === "0" // false0 === "" // false0 === "0" // falsefalse === "false" // falsefalse === "0" // falsefalse === undefined // falsefalse === null // falsenull === undefined // false" \t\r\n" === 0 // false

8-2. typeof 연산자, instanceof 연산자, Object.prototype.toString

JavaScript

8. Type

8-3. 타입 캐스팅

// 다음은 모두 truenew Number(10) == 10; // Number.toString()이 호출되고 다시 Number로 변환된다.10 == '10'; // 스트링은 Number로 변환된다.10 == '+10 '; // 이상한 스트링10 == '010'; // 엉뚱한 스트링isNaN(null) == false; // null은 NaN이 아녀서 0으로 변환된다.

// 다음은 모두 false10 == 010;10 == '-10';

• 기본 타입 생성자

- Number나 String 같은 기본 타입들의 생성자는 new 키워드가 있을 때와 없을 때 다르게 동작한다.

Copyright©2015 ABACUS, Co. All rights reserved. 28

- Number나 String 같은 기본 타입들의 생성자는 new 키워드가 있을 때와 없을 때 다르게 동작한다.

- new 키워드와 함께 Number 같은 기본 타입의 생성자를 호출하면 객체를 생성하지만 new 없이 호출하면 형 변환만 시킨다

new Number(10) === 10; // False, Object와 NumberNumber(10) === 10; // True, Number와 Numbernew Number(10) + 0 === 10; // True, 타입을 자동으로 변환해주기 때문에

• 스트링으로 변환하기 : '' + 10 === '10'; // true : 숫자를 빈 스트링과 더하면 쉽게 스트링으로 변환

• 숫자로 변환하기 : +'10' === 10; // true : + 연산자만 앞에 붙여주면 스트링을 쉽게 숫자로 변환

• Boolean으로 변환하기 : !!'foo'; // true : '!' 연산자를 두 번 사용하면 쉽게 Boolean으로 변환!!''; // false!!'0'; // true!!'1'; // true!!'-1' // true!!{}; // true!!true; // true

JavaScript

객체의 원형인 프로토타입을 이용하여 새로운 객체를 만드는 프로그램밍 기법

JavaScript의 모든 객체는 자신을 생성한 객체 원형에 대한 숨겨진 연결을 갖는다. 이떄 자기 자신을 생성 하기 위해 사용된 객체원

형을 프로토타입이라 함

JavaScript의 모든 객체는 Object객체의 프로토타입을 기반으로 확장 되었기 때문에 이 연결의 끝은 Object객체의 프로토타입

Object임

9-1. JavaScript Object prototype 란

9. JavaScript Object prototype

9-2. Prototype property 란 ?

• 모든 함수 객체의 Constructor는 prototype이란 프로퍼티를 가지고 있다.

• 이 prototype property는 Object가 생성될 당시 만들어지는 객체 자신의 원형이 될 prototype 객체를 가르킨다.

Copyright©2015 ABACUS, Co. All rights reserved. 29

function foo() {}var foo = new foo();

Foo

< host object >

__proto__

Prototype

foo Prototype

< Prototype object >

Constructor

__proto__

Object Prototype

< Built-in object >

__proto__ null

function Prototype

< Built-in object >

__proto__

Prototype link

Real link

JavaScript

9. JavaScript Object prototype

function foo(x) {this.x = x;

};

var A = new foo('hello'); console.log(A.x); // hello console.log(foo.prototype.x); // undefinedconsole.log(A.prototype.x) // Cannot read property 'x' of undefined

A 는 함수 객체가 아닌 foo라는 원형 함수 객체를통해 만들어진 Object 객체에 확장된 단일 객체 A 객체가 생성 시점에 foo의 prototype.x가 없음-> A는 prototype property를 소유하고 있지 않음

9-3. 예제 1

var A = function () { B,C 는 객체 생성시 A의 prototype Object를 사용함

9-4. 예제 2

Copyright©2015 ABACUS, Co. All rights reserved. 30

var A = function () {this.x = function () {

console.log('hello');};

};A.x=function() {

console.log('world');};var B = new A();var C = new A();B.x(); // helloC.x(); // helloA.x(); // world

B,C 는 객체 생성시 A의 prototype Object를 사용함 prototype Object는 A가 생성될 시점 정보만 가지고 있음A의 prototype Object가 알고 있는 x는 function () { console.log('hello');};임 A.x를 아무리 수정을 하여도 A의 prototype Object는변경되지 않았음

JavaScript

9. JavaScript Object prototype

var A = function () { };A.x=function() {

console.log('hello');};A.prototype.x = function () {

console.log('world');};var B = new A();var C = new A();B.x(); // worldC.x(); // worldA.x(); // hello

B,C 는 객체 생성시 A의 prototype Object를 사용함 prototype Object는 A가 생성될 시점 정보만 가지고 있음 A의 prototype.x를 world로 선언하였으로 B,C는 A의 prototype을 따라감

9-5. 예제 3

A

__proto__

Prototype

Function Prototype

__proto__C

Copyright©2015 ABACUS, Co. All rights reserved. 31

A.prototype.x = function () {console.log('world2');

};B.x(); // world2C.x(); // world2

Prototype

X

A Prototype

__proto__

Constructor

X

Object Prototype

__proto__ null

__proto__

X

B

__proto__

X

객체의 생성 과정에서 모태가 되는 프로토타입과의 연결고리가 이어져 상속관계를 통하여 상위 프로토타입으로연속해서 이어지는 관계를 프로토타입 체인이라고 한다. 이 연결은 __proto__ 를 따라 올라가게 된다.

JavaScript

9. JavaScript Object prototype

B는 x를 상속var A= function() {}; var B = new A(); A.prototype.x='hello'; console.log(A.prototype.x); // helloconsole.log(B.x); // hello B.x = 'world';console.log(A.prototype.x); // hello console.log(B.x); // world

9-6. 공유와 상속

A

__proto__

Prototype

A Prototype

__proto__

Constructor

X

B

__proto__

Copyright©2015 ABACUS, Co. All rights reserved. 32

B는 X를 공유var A= function() {

this.x='hello';}; var B = new A(); console.log(B); // { x: 'hello' }console.log(A); // [Function]

A

__proto__

Prototype

A Prototype

__proto__

Constructor

B

__proto__

X

JavaScript

9. JavaScript Object prototype

function Animal(name) {this.name = name;this.getName = function () {

console.log(this.name);}

}

var monkey = new Animal("Monkey");var dog = new Animal("dog");var cat = new Animal("cat");

monkey.getName(); // Monkeydog.getName(); // dog

9-7. 객체와 Prototype이차이점

Object.prototype.getName = function () {console.log(this.name);

}

function Animal(name) {this.name = name;

}

var monkey = new Animal("Monkey");var dog = new Animal("dog");var cat = new Animal("cat");

monkey.getName();

Copyright©2015 ABACUS, Co. All rights reserved. 33

dog.getName(); // dogcat.getName(); // cat

monkey

name

getName()

dog

name

getName()

cat

name

getName()

monkey.getName();dog.getName();cat.getName();

monkey

name

dog

name

cat

name

Object.prototype

getName()