General

Strict Mode (엄격 λͺ¨λ“œ)

슀크립트 상단 ν˜Ήμ€ ν•¨μˆ˜μ˜ μ‹œμž‘ λΆ€λΆ„μ˜ 'use strict' 을 μ„ μ–Έν•˜λ©΄ Strict Mode 둜 μ½”λ“œλ₯Ό μž‘μ„± ν•  수 μžˆλ‹€.

'use strict';

/* statement */
function foo () {
  'use strict';

  /* statement */
}

Strict Mode λŠ” 문법검사와 λŸ°νƒ€μž„ λ™μž‘μ„ κ²€μ‚¬ν•΄μ£ΌλŠ” κΈ°λŠ₯을 ν•˜λŠ”λ° κ·Έ μ—­ν™œμ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • κ²½κ³ λ₯Ό μ—λŸ¬λ‘œ λ³€ν™˜
  • read only κ°μ²΄λŠ” μˆ˜μ •λΆˆκ°€
  • get 으둜 μ„ μ–Έλœ κ°μ²΄λŠ” μˆ˜μ •λΆˆκ°€
  • extensible νŠΉμ„±μ΄ false 둜 μ„€μ •λœ 객체의 속성 ν™•μž₯ λΆˆκ°€
  • delete μ—°μ‚° μ‚¬μš© λΆˆκ°€
  • Literal Object 의 λ™μΌν•œ μ΄λ¦„μ˜ Property 생성 λΆˆκ°€
  • 8 μ§„μˆ˜ 및 Literal 및 escape λ¬Έ μ‚¬μš© λΆˆκ°€
  • κΈ°μ‘΄μ—λŠ” λ¬΄μ‹œλ˜λ˜ μ—λŸ¬λ“€μ„ Throwing ν•œλ‹€.
  • μ΅œμ ν™” μž‘μ—…μ„ 도와쀀닀. (νŠΉμ • 슀크립트 μ½”λ“œκ°€ 빨리 ν•΄μ„λ˜κ²Œλ” 함)
  • ν–₯ν›„ λ²„μ „μ—μ„œ μ •μ˜λ  문법듀을 κΈˆμ§€ν•œλ‹€.

일급객체 (First-Class Object)

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 일급객체 (First-Class Object) μž…λ‹ˆλ‹€.
일급 객체 (First-Class Object) λŠ” λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ κ°–μŠ΅λ‹ˆλ‹€.

  • 일급 κ°μ²΄λŠ” λ³€μˆ˜μ— μ €μž₯ κ°€λŠ₯ ν•΄μ•Ό ν•œλ‹€.
  • 일급 κ°μ²΄λŠ” ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달 ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.
  • 일급 κ°μ²΄λŠ” ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš© ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.
  • 일급 κ°μ²΄λŠ” μžλ£Œκ΅¬μ‘°μ— μ €μž₯ ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.

JSONP

μ›Ή λΈŒλΌμš°μ €λŠ” SOP (same origin policy: λ™μΌμΆœμ²˜μ •μ±…) 에 따라 μ„œλ‘œ λ‹€λ₯Έ λ„λ©”μΈκ°„μ˜ 데이터 톡신을 μ œν•œν•˜κ³  μžˆλ‹€
script μ½”λ“œκ°€ DOM νŠΈλ¦¬μ— μΆ”κ°€λ˜μ–΄ μ‹€ν–‰λ˜λ©΄ μ™ΈλΆ€ 슀크립트λ₯Ό λ‘œλ“œν•  수 μžˆλ‹€λŠ” 것 μ—μ„œ μ°©μ•ˆ
<script> νƒœκ·ΈλŠ” SOP 정책에 μ†ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— jsonp (json width padding) 이 μ‚¬μš©λ¨

Ajax n JSONP

JSONP 의 callback 은 μ„œλ²„μ—μ„œ 지원 ν•΄μ€˜μ•Ό μ •μƒμ μœΌλ‘œ μ‚¬μš©μ΄ κ°€λŠ₯

슀크립트 νƒœκ·Έ μ‚½μž…μœΌλ‘œ callback ν•¨μˆ˜ jsonp κ΅¬ν˜„ν•˜κΈ°

var callback = '_callback_jsonp_' + Math.round(10000 * Math.random());

var script = document.createElement('script');
script.src = 'http://localhost:8080/getJSON.json?callback=' + callback;
document.body.appendChild(script);

window[callback] = function (data) {
    delete window[callback];

    /* 콜백 μ‹€ν–‰ 둜직 */
}

μš”μ²­ URL 뒀에 callback νŒŒλΌλ©”ν„° μΆ”κ°€ν•˜μ—¬ jsonp μš”μ²­ κ΅¬ν˜„ν•˜κΈ°

Client

$.getJSON('/jsonp.json?callback=?', function (data) {
    console.log('success: ', data);
});

Server

private void doGet(HttpServletRequest request, HttpServleteResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");

    String id = request.getParameter("id");
    String callBack = request.getParameter("callback");
  
    JSONObject obj = new JSONObject();
    obj.put("result", id);
    obj.put("go", "ν…ŒμŠ€νŠΈ");

    PrintWriter out = response.getWriter();
    out.write(callBack + "(" + obj.toString() + ")");
    System.out.println(callBack + "(" + obj.toString() + ")");
    out.flush();
    out.close();
}

μš”μ²­ json 에 callback ν•¨μˆ˜λ‘œ ν•œλ²ˆ κ°μ‹Έμ„œ jsonp κ΅¬ν˜„ν•˜κΈ°

Client

$.ajax({
  url: "/jsonp.json",
  dataType: 'jsonp',
  jsonpCallback: "myCallback",
  success: function(data) {
    console.log('성곡 - ', data);
  },
  error: function(xhr) {
    console.log('μ‹€νŒ¨ - ', xhr);
  }
});

Server

myCallback({"message":"You got an AJAX response via JSONP from another site!"});

jsonpCallback μ˜΅μ…˜ 없이 μ‚¬μš©ν•˜κΈ°

Client

$.ajax({
  url: "/jsonp.json",
  dataType: 'jsonp',
  success: function(data) {
    console.log('성곡 - ', data);
  },
  error: function(xhr) {
    console.log('μ‹€νŒ¨ - ', xhr);
  }
});

Server

jQuery18305806868467951786_1366340807385({"key":"value"});

jsonp 둜 전달 λ°›λŠ” μ‘λ‹΅λ°μ΄ν„°λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

_callback_jsonp_({
  "code": 1,
  "message": "success",
  "result_set": {}
});

TIP

전달 λ°›λŠ” 데이터λ₯Ό 콜백 ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜μ—¬ μ‹€ν–‰ μ‹œν‚€λŠ” ꡬ쑰
CORS 섀정을 ν•œλ‹€λ©΄ λ³„λ„μ˜ jsonp μž‘μ—…μ€ ν•„μš” μ—†λ‹€.
μš”μ²­ λ°μ΄ν„°μ˜ 응닡 헀더가 Access-Control-Allow-Orign: * 으둜 λ³€κ²½

암묡적 μ „μ—­

μžλ°”μŠ€ν¬λ¦½νŠΈ 내에 λ³€μˆ˜ μ„ μ–Έμ‹œμ— μ„ μ–Έμž (var) κ°€ μ—†μœΌλ©΄ 암묡적 μ „μ—­ 으둜 인해 μ „μ—­ ν”„λ‘œνΌν‹° (window object property) 둜 등둝 λœλ‹€.

var a = 0;
b = 2;
(function () {
    c = 3;
}());

delete a;
delete b;
delete c;

console.log(typeof a);        // number
console.log(typeof b);        // undefined
console.log(typeof c);        // undefined

ν”„λ‘œνΌν‹°λŠ” delete μ—°μ‚°μžλ‘œ μ‚­μ œ κ°€λŠ₯

상속 (Inheritance)

ν”„λ‘œν†  νƒ€μž…μ„ μ΄μš©ν•œ ν™•μž₯

μžλ°”μŠ€ν¬λ¦½νŠΈμ—λŠ” μžλ°”μ™€ 달리 class κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„ prototype 을 μ‚¬μš©ν•˜μ—¬ class λ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.

상속 Class 생성

Example #1 : JS - ES5

function Shape() {
    this.x = 0;
    this.y = 0;
}

Shape.prototype.move = function (x, y) {
    this.x += x;
    this.y += y;
}

function Rectangle() {
    Shape.call(this);
}

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

상속 객체 생성

Example #1 : JS - ES5

var rect = new Rectangle();

console.log(rect instanceof Rectangle);
console.log(rect instanceof Shape);

rect.move(1, 1);

ν”„λ‘œν† νƒ€μž…μ˜ ν™•μž₯을 μ΄μš©ν•œ 방법 은 Monkey Patching 이라고도 ν•˜λ©° ꢌμž₯ν•˜μ§€ μ•ŠλŠ” 방법 이닀.

Object.create() λ₯Ό μ΄μš©ν•œ λ©”μ†Œλ“œ 상속

Example #1 : JS - ES5

var parent = {
    num: 2,
    increase: function () {
        return (this.num + 1);
    }
}

console.log(parent.increase());     // 3

var child = Object.create(parent);

child.num = 12;

console.log(child.increase());    // 13

μžλ£Œν˜• (λ³€μˆ˜ν˜•) 에 λŒ€ν•œ 차이점

ES 5 & 6 에 μ§€μ›ν•˜λŠ” μžλ£Œν˜• (λ³€μˆ˜ν˜•) var let const 은 λ‹€μŒκ³Ό 같은 차이점을 가진닀.

var let const
μœ νš¨λ²”μœ„ function scope block scope block scope
μž¬ν• λ‹Ή O O X

ν˜Έμ΄μŠ€νŒ… (Hoisting)

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό μƒμ„±ν•˜λ©΄μ„œ scope λ₯Ό μ •μ˜ν•  λ•Œ 기술된 μˆœμ„œμ— 상관없이 선언뢀에 λŒ€ν•œ 처리 ν•΄μ„μ˜ μš°μ„ μˆœμœ„λ₯Ό μ΅œμš°μ„ μœΌλ‘œ λŒμ–΄μ˜¬λ € λ¨Όμ € 해석 ν•˜λŠ” 것
μ΄λŠ” λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ κ°–λŠ”λ‹€.

  • λ³€μˆ˜μ˜ μ •μ˜κ°€ κ·Έ λ²”μœ„μ— 따라 μ„ μ–Έκ³Ό ν• λ‹ΉμœΌλ‘œ 뢄리 ν•œλ‹€.
  • μ„ μ–Έκ³Ό 할당이 λΆ„λ¦¬λ˜λ©° μ—λŸ¬λ₯Ό μ•ΌκΈ°μ‹œν‚¬ 수 μžˆλ‹€.
  • ES6 μ—μ„œλŠ” ν˜Έμ΄μŠ€νŒ…μ˜ 지원이 μ—†μ–΄μ‘Œλ‹€. (ES5 μ‹μ˜ ν˜Έμ΄μŠ€νŒ… / TDZ 관점)
  • κΈ°μ‘΄ ES5 μ—μ„œλŠ” ν˜Έμ΄μŠ€νŒ…μ΄ μžˆμ–΄ ν•΄λ‹Ή 값을 μ„ μ–Έ ν›„ ν˜ΈμΆœν•˜λ©΄ undefined 둜 λ‚˜μ˜¨λ‹€.

예제 μ½”λ“œ

Example #1 : JS - ES5

var value = 'outer scope';
(function () {
    console.log(value);        // undefined
    var value = 'inner scope';
});

μœ„ μ½”λ“œλŠ” μ•„λž˜μ™€ 같이 해석 λœλ‹€.

var value = 'outer scope';
(function () {
    var value;

    // undefined
    console.log(value);
    var value = 'inner scope';
});

var 에 λΉ„ν•΄ const/let 은 TDZ 에 μ˜ν•΄μ„œ ReferenceError κ°€ λ°œμƒν•œλ‹€.

const value = 'outer scope';

(function () {
    console.log(value);
    const value = 'inner scope';
}());

TDZ (Temporal Dead Zone) ?

μ΄ˆκΈ°ν™” (μ„ μ–Έ) κ°€ λ˜μ§€ μ•ŠλŠ” 객체듀을 μ°Έμ‘° ν•  수 μ—†λ‹€.
ν˜Έμ΄μŠ€νŒ…μ΄ λ˜μ§€ μ•ŠλŠ”κ²ƒμ€ μ•„λ‹˜ - ES5 처럼 undefined 둜 μ„  할당이 μ•ˆλ¨

ν•¨μˆ˜μ˜ μ„ μ–Έκ³Ό ν‘œν˜„μ‹

ν•¨μˆ˜ 선언식 (Function Declarations / Function Statement)

μ‹€ν–‰ κ°€λŠ₯ν•œ μƒνƒœκ°€ μ•„λ‹ˆλ©° ν•¨μˆ˜μ˜ μ •μ˜λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Statement 으둜 μ½”λ“œ 해석에 λ”°λ₯Έ μˆ˜ν–‰ κ²½κ³Όκ°€ 쑴재 ν•˜μ§€ μ•ŠλŠ”λ‹€.

Example #1 : JS - ES5

// ν•¨μˆ˜ 선언식
function foo() {
  /* statement */
}

ν•¨μˆ˜ ν‘œν˜„μ‹ (Function Expressions / Function Literal)

μ‹€ν–‰ κ°€λŠ₯ν•œ μƒνƒœ μ½”λ“œ 둜 ν•΄μ„λ˜μ–΄ μ§€κ±°λ‚˜ ν˜Ήμ€ λ³€μˆ˜λ‚˜ 데이터 ꡬ쑰에 ν• λ‹Ή λ˜μ–΄ μžˆμŒμ„ μ˜λ―Έν•œλ‹€.

Example #1 : JS - ES5

// ν•¨μˆ˜ ν‘œν˜„μ‹
var foo = function () {
  /* statement */
}

ν•¨μˆ˜μ˜ 선언식은 ν˜Έμ΄μŠ€νŒ…μ— 영ν–₯ 을 λ°›μ§€λ§Œ, ν•¨μˆ˜μ˜ ν‘œν˜„μ‹μ€ ν˜Έμ΄μŠ€νŒ…μ— 영ν–₯을 받지 μ•ŠλŠ”λ‹€.

읡λͺ… ν•¨μˆ˜ (Anonymouse Function)

ν•¨μˆ˜μ˜ 선언이 μ•„λ‹Œ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ μ΄μš©ν•˜λŠ” 방법 이며 μ¦‰μ‹œ μ‹€ν–‰ ꡬ문을 λ§Œλ“€λ•Œ 많이 μ‚¬μš©λœλ‹€.

읡λͺ… ν•¨μˆ˜λŠ” λ™μ μœΌλ‘œ ν• λ‹Ήλ˜λŠ” μœ νš¨λ²”μœ„λ₯Ό 가지기 λ•Œλ¬Έμ— κ°•μ œμ μΈ μœ νš¨λ²”μœ„λ₯Ό μ„€μ • ν•˜λŠ” κ²½μš°μ—λ„ μ‚¬μš© λœλ‹€.

Example #1 : JS - ES5

(function () {
  var value = 'Hello World';
}());

console.log(value);     // ReferenceError: value is not defined

μ¦‰μ‹œ μ‹€ν–‰ ꡬ문 (IIFE : Immediately-Invoked Function Expression)

읡λͺ… ν•¨μˆ˜ (Anonymouse Function) λ₯Ό μ΄μš©ν•˜μ—¬ λ°”λ‘œ μ‹€ν–‰ κ°€λŠ₯ν•œ ν•¨μˆ˜ ν‘œν˜„μ‹μ„ 이용 ν•˜μ—¬ λ§Œλ“€μ–΄ λ‚΄λŠ” ꡬ문

Syntax

(function () {
  /* μ‹€ν–‰μ½”λ“œ */
}());

Example

기본적인 μ‚¬μš©λ²•

(function () { /* statement */ })();
(function () { /* statement */ }());
(() => { /* statement */ })(); // With ES6 arrow functions (though parentheses only allowed on outside)

λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ 싀행을 κ°•μ œν•˜λŠ” 방법

!function () { /* statement */ }();
~function () { /* statement */ }();
-function () { /* statement */ }();
+function () { /* statement */ }();
void function () { /* statement */ }();