프론트엔드스터디 e04 js function

41
프프프프프 프프프 CH.04. JS function

Upload: young-beom-rhee

Post on 16-Apr-2017

10.449 views

Category:

Engineering


3 download

TRANSCRIPT

Page 1: 프론트엔드스터디 E04 js function

프론트엔드 스터디CH.04. JS function

Page 2: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4.다른 언어와 다른 유효범위 Scope

+@ 재귀함수를 구현하는 3 가지 방법

Page 3: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4. 다른 언어와 다른 유효범위 Scope

+@ 재귀함수를 구현하는 3 가지 방법

Page 4: 프론트엔드스터디 E04 js function

함수 (function) 란 ?

호출되거나 실행될 수 있는 자바스크립트 코드 블록

모듈화의 근간

자바스크립트는 함수형 언어

일급객체 (First class citizen)

1. 기본개념

Page 5: 프론트엔드스터디 E04 js function

– 일급객체 First citizen 다음과 같은 조건을 만족할 때 일급

객체라고 말할 수 있다 .

- 변수나 데이터 구조안에 담을 수있다 .

- 파라미터로 전달 할 수 있다 .

- 반환값 (return value) 으로 사용할 수 있다 .

1. 기본개념

var func = function () {};

return function(){};

func(function(){});

Page 6: 프론트엔드스터디 E04 js function

함수 vs. 메서드

console.dir() 은 함수일까 ? 메서드일까 ?

vs.

1. 기본개념

function funcA() { /* 코드 블록 */}

var objA = { funcA : function() { /* 코드 블록 */ }}

Page 7: 프론트엔드스터디 E04 js function

함수 vs. 메서드

함수를 객체의 속성에 저장하는 경우

=> 메서드 (method)

console.dir() 의 dir 역시console 객체의 하나의 속성

1. 기본개념

Page 8: 프론트엔드스터디 E04 js function

내장함수 (built-in function)

미리 생성되어 있는 함수들

parseInt(), Math.exp() 등등

전역에 선언되어 있기 때문에 어느 곳에서나 호출 가능

1. 기본개념

Page 9: 프론트엔드스터디 E04 js function

함수의 종류

FunctionDeclaration vs. FunctionExpression

* FunctionDeclaration 은 Hoisting 이 발생한다 . ( 단 , 정식명칭은 아니다 .)

1. 기본개념

Quiz.

funcA();function funcA() { console.log('funcA has called');} // 호출됨

funcB();var funcB = function() { console.log('funcB has called');}; // 에러

Page 10: 프론트엔드스터디 E04 js function

Quiz.

1. 기본개념

각각의 출력 결과는 ?

console.log(a);function a() {};var a = 1;console.log(a);

console.log(a);var a = 1;function a() {};console.log(a);

console.log(a);var a = 1;var a = function(){};console.log(a);

Page 11: 프론트엔드스터디 E04 js function

그 외의 함수들즉시실행함수

1. 기본개념

중첩된 함수 혹은 내부함수

=> closure

(function(){ console.log("Right now!")})();

function a() { return function() { }}

Page 12: 프론트엔드스터디 E04 js function

함수 전달인자 - arguments

=> 가변전달인자 varargs(variable length arguments)

1. 기본개념

function maxNum(/* 어떤 값이 들어와도 상관 없음 */) { var max = Number.NEGATIVE_INFINITY; for(var idx in arguments) { if(!isNaN(arguments[idx]) && arguments[idx]>max) { max = Number(arguments[idx]); } } return max;}

maxNum(1, 21, 3, undefined, 5, 123, false, '1234', 'test');

Page 13: 프론트엔드스터디 E04 js function

Arguments 객체- 함수 내부에 존재하는 객체

1. 기본개념

function dirArgu(/* 파라미터 선언 없음 */) { console.dir(arguments);}

dirArgu(1);

dirArgu(1,2,3,4,5,6,7);

Page 14: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4. 다른 언어와 다른 유효범위 Scope

+@ 재귀함수를 구현하는 3 가지 방법

Page 15: 프론트엔드스터디 E04 js function

호출패턴과 this

1. 메서드 호출 패턴

- 호출하는 패턴에 따라 this 라는 추가적인 매개변수를 다르게 초기화 한다 .

2. 호출패턴 에 따라 달라지는

this

var objA = { sum : 0 , add : function(addVal) { this.sum += addVal; return this.sum; }}

objA.sum;objA.add(2);objA.add(3);

var directAddCall = objA.add;directAddCall(2); this === objA

this === window

★ This -> 호출한 함수가 속한 오브젝트를 참조

Page 16: 프론트엔드스터디 E04 js function

2. 함수 호출 – use strict

2. 호출패턴 에 따라 달라지는

this

this === window

this === undefined

this === window

function funcA() { console.dir(this);};

console.dir(funcA());

function funcA() { "use strict"; console.dir(this);};

funcA();window.funcA();

use strict : 따로 언급하지 않는 이상 window 에 매핑되는 모호함을 허용하지 않음 .

Page 17: 프론트엔드스터디 E04 js function

3. 생성자에서 호출

2. 호출패턴 에 따라 달라지는

this

this === FuncA

function FuncA() {};var funcB = new FuncA();

FuncA.prototype.checkThis = function(){ console.dir(this);};

funcB.checkThis();

Page 18: 프론트엔드스터디 E04 js function

4. call 과 apply

2. 호출패턴 에 따라 달라지는

this

function A(a,b,c) { console.log(this.x, this.y, a, b, c);}

A();

A.call({x:1,y:2}, 3, 4, 5);

A.apply({x:1,y:2}, [6, 7, 8]);

명시적으로 this 에mapping 시킬

프로퍼티들을 넘길 수 있다

Page 19: 프론트엔드스터디 E04 js function

+@ bind 를 통한 this mapping

2. 호출패턴 에 따라 달라지는

this

call, apply -> 호출시점에 일시적인 매핑

bind -> 영구적인 Binding

var newA = A.bind({x:3,y:4});

var newA2 = A.bind({x:3,y:4});

Page 20: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4. 다른 언어와 다른 유효범위 Scope

+@ 재귀함수

Page 21: 프론트엔드스터디 E04 js function

함수의 프로토타입 상속

3. 상속을 가능하게 해주는 Prototype

=> __proto__ 는 생성자의 prototype 을 바라보고 있다 .

function FuncA() {}var funcA1 = new FuncA();

console.dir(funcA1);

FuncA.prototype.addedMethod = function(){ console.log("I'm added"); };

console.dir(funcA1);

Page 22: 프론트엔드스터디 E04 js function

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

Person.prototype.getName = function () { return this.name;}

Person.prototype.setName = function (name) { this.name = name;}

var personA = new Person("personA");var personB = new Person("personB");var personC = new Person("personC");

console.log(personA.getName());console.log(personB.getName());console.log(personC.getName());

공통속성을 추가하는 경우– Prototype 을 이용

Instance 마다 개별적으로 가져야 할 프로퍼티

공통으로 가져야 할프로퍼티

Page 23: 프론트엔드스터디 E04 js function

cf. Prototype 을 사용하지 않은 경우

Prototype 참조

Page 24: 프론트엔드스터디 E04 js function

변경이 발생했을 때

Person.prototype.getName = function () { return 'Hello, ' + this.name;}

console.log(personA.getName());console.log(personB.getName());console.log(personC.getName());

Hello, personAHello, personBHello, personC

Prototype 을 참조하고 있는 다른 모든 Instance 에도 모두 적용

Page 25: 프론트엔드스터디 E04 js function

Prototype 의 몇 가지 속성

name : name / hasOwnProperty : truename : getName / hasOwnProperty : falsename : setName / hasOwnProperty : false

for (var obj in personA) { console.log('name : ', obj, ' / hasOwnProperty : ' + personA.hasOwnProperty(obj));}

- 마치 자신의 속성처럼 열거할 수 있다 .(for in 사용 )- hasOwnProperty() 메서드를 사용해 소유여부 ( 자신이

소유하고 있는지 , prototype 으로 참조하는지 ) 를 확인할 수 있다 .

Page 26: 프론트엔드스터디 E04 js function

function Circle(r) { this.r = r;}

Circle.prototype.PI = 3.14;

Circle.prototype.getArea = function () { return 2 * this.r * this.PI;}

var r2 = new Circle(2);console.log(r2.getArea());

var r3 = new Circle(3);console.log(r3.getArea());

var r3Alien = new Circle(3);r3Alien.PI = 4.74; // PI 재정의console.log(r3Alien.getArea());

내부의 property 가 있는 경우에 prototype 을 참고하지 않는다 . 이런 경우를 다른 property 가 가렸다 (shadows) 혹은 숨겼다

(hides) 라고 한다

- Prototype property 가 참조되지 않을 수 있다 .

Page 27: 프론트엔드스터디 E04 js function

Function.prototype.addMethod = function (name, func) { if(!this.prototype[name]) { this.prototype[name] = func; }}

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

Person.addMethod('setName', function(name) { this.name = name;});

Person.addMethod('getName', function () { return this.name;});

var personA = new Person("personA");var personB = new Person("personB");var personC = new Person("personC");

크락포드옹 스탈

Overriding 을 방지할 수 있다

Page 28: 프론트엔드스터디 E04 js function

Function 의 용도가 2 가지: 실행을 위한 함수 , 생성자 함수

혼란을 피하기 위해 생성자 함수는 대문자로 시작하도록 권고

크락포드옹님 주의사항

Page 29: 프론트엔드스터디 E04 js function

* prototype chaining 맛보기

3. 상속을 가능하게 해주는 Prototype

var a = { func : function(){ console.log(this.val); }};

var b = Object.create(a);var c = Object.create(b);var d = Object.create(c);var e = Object.create(d);

b.val = 'b.val';a.val = 'a.val';e.func(); // b.val

e .__proto__ .__proto__ .__proto__ .__proto__ === a; // true

Page 30: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4. 다른 언어와 다른 유효범위 Scope

+@ 재귀함수를 구현하는 3 가지 방법

Page 31: 프론트엔드스터디 E04 js function

Quiz.

a = ?

4. 다른 언어와 다른 유효범위

Scope

function aa() { var a = 1; function b() { var a = 2; c(); } function c() { console.log(a); } b();}

aa();

Page 32: 프론트엔드스터디 E04 js function

Quiz. 항목별 유효범위

4. 다른 언어와 다른 유효범위

Scope

항목별 Scope 는

어떻게 될까 ?

outer()inner()x, a, b, c

function outer() { debugger; inner(); var a = 1; function inner() { var x = 2; } var b = 2; if(a==1) { var c = 3; } console.log(c);}outer();

Page 33: 프론트엔드스터디 E04 js function

항목별 유효범위4. 다른 언어와 다른 유효범위

Scope

* JavaScript 의 Scope 는 블록단위가 아니라 함수 단위

function outer() { debugger; inner(); var a = 1; function inner() { var x = 2; } var b = 2; if(a==1) { var c = 3; } console.log(c);}outer();

!! If 블록을 넘어간다 .

Scope 결정요소 :

어디에선언되었느냐 ?

변수냐 ? 함수냐 ?

outer()

inner()

x a b c

Page 34: 프론트엔드스터디 E04 js function

블록 vs. 함수 유효범위C, Java 등의 언어의 유효범위 : { } (Block)

블록이 끝났다고 (}) 유효범위가 끝나지

않는다 .⇒ JavaScript 의

유효범위 : 함수

4. 다른 언어와 다른 유효범위

Scope

if(window) { var x =123;}console.log(x);

Page 35: 프론트엔드스터디 E04 js function

1.기본개념 부터 잡아보자

2.호출패턴 에 따라 달라지는 this

3. 상속을 가능하게 해주는 Prototype

4. 다른 언어와 다른 유효범위 Scope

+@ 재귀함수를 구현하는 3 가지

방법

Page 36: 프론트엔드스터디 E04 js function

Quiz.

+@ 재귀함수를 구현하는 3 가지

방법

arguments? callee?

괄호는 왜 2 개 ?

function factorial() { return function(x) { if (x <= 1) return 1; else return x * arguments.callee(x-1); };}

factorial()(5);

Page 37: 프론트엔드스터디 E04 js function

Quiz.

+@ 재귀함수를 구현하는 3 가지

방법

function factorial() { return function(x) { if (x <= 1) return 1; else return x * arguments.callee(x-1); };}

factorial()(5);

arguments? -> 함수가 실행될 때 생성되는 객체callee? -> 자신을 호출한 객체

괄호는 왜 2 개 ? -> 첫 번째 괄호는 실행 후에function(x) 를 리턴 . 두 번째 괄호를 통해function(x) 를 실행 .

Page 38: 프론트엔드스터디 E04 js function

재귀 - Function Declaration

=> 어느 곳에서든지 이름으로 호출 가능

+@ 재귀함수를 구현하는 3 가지

방법

function factorial(x) { if (x <= 1) return 1; else return x * factorial(x-1);}

factorial(5);

Page 39: 프론트엔드스터디 E04 js function

– 재귀 메서드 (Function Expression)

=> 익명 함수에 이름을 주면 함수 내에서 사용할 수 있다 .

+@ 재귀함수를 구현하는 3 가지

방법

var factorial = function recurs(x) { if (x <= 1) return 1; else return x * recurs(x-1);}

factorial(5);

Page 40: 프론트엔드스터디 E04 js function

– 재귀 arguments.callee (deprecated)

=> 함수가 호출되는 시점에 자신을 호출한 객체를 arguments.callee 에 할당한다 .

+@ 재귀함수를 구현하는 3 가지

방법

var factorial = function(x) { if (x <= 1) return 1; else return x * arguments.callee(x-1);}

factorial(5);

Page 41: 프론트엔드스터디 E04 js function

참고자료

- http://www.ecma-international.org/ecma-262/5.1/

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/

Reference/Operators/this

- 자바스크립트 완벽가이드 데이비드 플래너건

- 자바스크립트 핵심 가이드 더글라스 크락포드

- 자바스크립트 닌자 비급 존 레식 , 베어 바이볼트

- 몰입 ! 자바스크립트 김영보

2. 호출패턴 에 따라 달라지는

this