Created
December 30, 2018 12:09
-
-
Save kimyongin/26b54f4d8fbecd4aae88dd77a7ed8496 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
// This & Binding (Implicit, Explicit, Hard, New) & Arrow Function (Lexical Scope) | |
// ------------------------------------------------------------------------------- | |
// [1.기본 바인딩] hello(thing) 은 hello.call(this, thing) 의 syntactic sugar 이다. | |
console.log("[1]") | |
function hello(thing) { | |
console.log(this + " hello " + thing); | |
} | |
hello("hola"); // undefined hello hola; (this가 암시적 바인딩 되었다. non-strict-mode 에서는 window 가 바인딩 된다.) | |
hello.call("kim", "hola") // kim hello hola; (this가 명시적 바인딩 되었다.) | |
// ------------------------------------------------------------------------------- | |
// [2.객체 바인딩] 함수 호출시점에 함수 레퍼런스(hello)에 대한 콘텍스트 객체(person)가 존재하면, | |
// 암시적 바인딩 규칙에 의해, 해당 콘텍스트 객체가 this 에 바인딩 된다. | |
console.log("[2]") | |
var person = { | |
name: "park", | |
hello: function (thing) { | |
if (!this) { | |
console.log("this is undefiend"); | |
} else { | |
console.log(this.name + " hello " + thing); | |
} | |
} | |
} | |
person.hello("hola") // park hello hola (this가 person 으로 암시적 바인딩 되었다.) | |
person.hello.call({ name: "choi" }, "hola") // choi hello hola (this가 명시적 바인딩 되었다.) | |
// ------------------------------------------------------------------------------- | |
// 아래 처럼 객체를 통하지 않고, 함수 레퍼런스를 직접 호출하면 | |
// 콘텍스트 객체 암시적 바인딩[2] 이 아니라, 일반 암시적 바인딩[1] 방식으로 호출 된다. | |
console.log("[3]") | |
function func(fn, thing) { | |
fn(thing); | |
} | |
func(person.hello, "hola"); // this is undefiend | |
var personHello = person.hello; personHello("hola"); // this is undefiend | |
// ------------------------------------------------------------------------------- | |
// 위와 같이 컨텍스트 객체를 잃어버리는 문제는 하드 바인딩으로 해결할 수 있다. | |
// 이는 ES5 Function.prototype.bind로 내장 되어 있다. | |
console.log("[4]") | |
function hardBind(fn, obj) { | |
return function (args) { | |
// 어떤식으로 호출하든, 항상 obj가 this에 하드 바인딩 된다 | |
fn.call(obj, args); | |
} | |
} | |
func(hardBind(person.hello, person), "hola"); // park hello hola | |
var personHello = hardBind(person.hello, person); personHello("hola") // park hello hola | |
func(person.hello.bind(person), "hola"); // park hello hola (내장 함수 사용) | |
var personHello = person.hello.bind(person); personHello("hola") // park hello hola (내장 함수 사용) | |
// ------------------------------------------------------------------------------- | |
// new 연산자를 통해서 객체를 생성하는 경우 new 바인딩 이 동작한다. | |
// new 바인딩은 this 에 새로운 객체를 바인딩 시킨다. | |
console.log("[5]") | |
function Person(name) { | |
this.name = name; | |
this.hello = function (thing) { | |
if (!this) { | |
console.log("this is undefiend"); | |
} else { | |
console.log(this.name + " hello " + thing); | |
} | |
} | |
} | |
var kim = new Person("kim"); | |
kim.hello("hola"); // kim hello hola | |
// 여기서도 마찬가지로, 객체를 통하지 않고, 함수 레퍼런스를 직접 호출하면 일반 암시적 바인딩으로 호출된다. | |
var kimHello = kim.hello; kimHello("hola"); // this is undefined | |
// ------------------------------------------------------------------------------- | |
// new 호출은 아래 처럼 호출 된다고 추측해 볼수 있다. | |
// 사실은 new를 통해 생성된 객체는 프로토타입 연결이라는 상속과 관련된 메카니즘이 추가되어 있다. | |
console.log("[6]") | |
var park = Object.create({}); | |
Person.bind(park)("park"); | |
park.hello("hola"); | |
// ------------------------------------------------------------------------------- | |
// 지금까지 Implicit, Explicit, Hard, New 4가지 바인딩을 살펴봤는데, | |
// 반면 Arrow Function 은 바인딩이 아니라, 렉시컬 스코프로 this 를 접근한다. | |
console.log("[7]") | |
function Person(name) { | |
var that = this; | |
this.name = name; | |
this.hello = function (thing) { | |
console.log(that.name + " hello " + thing); | |
} | |
this.hello2 = (thing) => { | |
console.log(this.name + " hello " + thing); | |
} | |
} | |
var choi = new Person("choi"); | |
choi.hello("hola"); // choi hello hola | |
var choiHello = choi.hello; choiHello("hola"); // choi hello hola | |
choi.hello2("hola"); // choi hello hola | |
var choiHello2 = choi.hello2; choiHello2("hola"); // choi hello hola |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment