Make it to make it

いろいろ作ってアウトプットするブログ

this: Implicit binding / Explicit binding

Implicit binding

次のようなファクトリーファンクションがあるとする。 いわゆる実行時にオブジェクトを返却するファンクション。

/**
 * Implicit Binding
 *     Left of the dot at call time
 */
const Person = function(name, age) {
  return {
    name,
    age,
    sayName() {
      console.log(this.name)
    },
    mother: {
      name: 'Tracy',
      sayName() {
        console.log(this.name)
      }
    }
  }
}
const john = Person('John', 49)

john.sayName()  // John
john.mother.sayName()  // Tracy

この場合、JohnとTracyがコンソールログされることになる。 ここでのthisは直上のプロパティを示す。

Explicit binding

よく混同しがちなcall, apply, bindを交えながら。 以下のようなファンクションとオブジェクト、配列を定義する。

/**
 * Explicit Binding
 *     call, apply, bind
 */
const sayName = function (lang) {
  console.log(`My name is ${this.name}, and I know ${lang.join(', ')}!`)
}
const sayName2 = function (lang) {
  console.log(`My name is ${this.name}, and I know ${lang}!`)
}
const stacey = {
  name: 'Stacey',
  age: 30,
}
const languages = ['JavaScript', 'Ruby', 'Python']

callメソッド

引数をそのまま一つずつ渡す。

// `call`: Pass arguments one by one
sayName.call(stacey, languages)

実行結果

My name is Stacey, and I know JavaScript, Ruby, Python! 

applyメソッド

引数を配列のアイテムとして渡す。下記の例の場合だと1番目が返却される。

// `apply`: Pass arguments as an array
sayName2.apply(stacey, languages)

実行結果

My name is Stacey, and I know JavaScript! 

bindメソッド

callメソッドと同じだが、こちらはファンクションを返す。

// `bind`: Same as `call` but returns a new function
const newSayName = sayName.bind(stacey, languages)
newSayName()

実行結果

My name is Stacey, and I know JavaScript, Ruby, Python!