What's this -- いまさら聞けない JavaScript の this

What's this -- いまさら聞けない JavaScript の this

JavaScript の this は関数定義時に決まるのではなく、関数の呼び出し方によって変わることを解説します。

Ca0ab6e450f894e06652ee257df9d647?s=128

Shuhei Kagawa

October 31, 2014
Tweet

Transcript

  1. What’s “this”? ͍·͞Βฉ͚ͳ͍ JavaScript ͷ this @M3 Tech Talk 2014/10/31

    ߳઒ पฏ
  2. ͜͏͍͏ίʔυʹݟ֮͑͸͋Γ·ͤΜ͔ʁ var header = { init: function(selector) { this.el =

    $(selector); this.el.find('.show-modal').on('click', function(e) { this.showModal(); }); this.el.find('.hide-modal').on('click', function(e) { this.hideModal(); }); }, showModal: function() { /* Show modal */ }, hideModal: function() { /* Hide modal */ } }; header.init('.header');
  3. ͜ͷίʔυ͸ಈ͖·ͤΜ var header = { init: function(selector) { this.el =

    $(selector); this.el.find('.show-modal').on('click', function(e) { this.showModal(); }); this.el.find('.hide-modal').on('click', function(e) { this.hideModal(); }); }, showModal: function() { /* Show modal */ }, hideModal: function() { /* Hide modal */ } }; header.init('.header');
  4. this ʹԿ͕ೖͬͯ͘Δ͔ Ͳ͏΍ܾͬͯ·ΔͰ͠ΐ͏ʁ 1. this ΛแΉؔ਺ͷఆٛ࣌ͷείʔϓͰܾ·Δɻ 2. this ΛแΉؔ਺ͷఆٛͷ࢓ํͰܾ·Δɻ 3.

    this ΛแΉؔ਺ͷ࣮ߦ࣌ͷείʔϓͰܾ·Δɻ 4. this ΛแΉؔ਺ͷ࣮ߦͷ࢓ํͰܾ·Δɻ
  5. this ʹԿ͕ೖͬͯ͘Δ͔ Ͳ͏΍ܾͬͯ·ΔͰ͠ΐ͏ʁ 1. this ΛแΉؔ਺ͷఆٛ࣌ͷείʔϓͰܾ·Δɻ 2. this ΛแΉؔ਺ͷఆٛͷ࢓ํͰܾ·Δɻ 3.

    this ΛแΉؔ਺ͷ࣮ߦ࣌ͷείʔϓͰܾ·Δɻ 4. this ΛแΉؔ਺ͷ࣮ߦͷ࢓ํͰܾ·Δɻ
  6. this ͸ 0 ݸ໨ͷҾ਺ • this ͸ɺؔ਺ͷఆٛ࣌Ͱ͸ͳ͘ɺؔ਺ͷݺͼग़͠ํ ʹΑ࣮ͬͯߦ࣌ʹܾ·Δɻ

  7. ؔ਺ݺͼग़͠ͷύλʔϯ 1. ϝιουݺͼग़͠: obj.func() 2. ؔ਺ݺͼग़͠: func() 3. ίϯετϥΫλݺͼग़͠: new

    Func() 4. call, apply: func.call(obj), func.apply(obj) 5. ଞͷਓʹ࣮ߦΛ೚ͤΔ: ΠϕϯτϦεφʔͳͲ
  8. 1. ϝιουݺͼग़͠ • obj.func() ͱ͢Δͱɺthis ͸ obj ʹͳΔɻ var world

    = { name: ‘World’, greet: function(greeting) { console.log(greeting + ‘, ‘ + this.name); } }; world.greet(‘Hello’); // Hello, World!
  9. 2. ؔ਺ݺͼग़͠ function greet(greeting) { console.log(greeting + ‘, ‘ +

    this.name); } greet(‘Hello’); // Hello, undefined var name = ‘Window’; greet(‘Hello’); // Hello, Window • func() ͱ͢Δͱɺthis ͸άϩʔόϧΦϒδΣΫτʢϒϥ΢βͰ ͸ windowʣʹͳΔɻ
  10. ‘use strict’; Λ࢖͓͏ function world() { 'use strict'; console.log('Hello, '

    + this.name); } world(); // TypeError: Cannot read property 'name' of undefined • ͨͩ͠ strict mode ͩͱ undefined ʹͳΓɺΤϥʔʹؾ ͖ͮ΍͍͢ɻ
  11. 3. ίϯετϥΫλݺͼग़͠ function Person(name, age) { this.name = name; this.age

    = age; } var shuhei = new Person('shuhei', 32); console.log(shuhei.name, shuhei.age); // shuhei 32 • new func() ͷܗࣜͰݺͼग़͢ͱɺthis ͸ίϯελϥΫλ ͕ฦ͢ΠϯελϯεʹͳΔɻ
  12. 4. call, apply function greet(greeting) { console.log(greeting + ', '

    + this.name); } greet.call({ name: 'call' }, ‘Hi'); // Hi, call greet.apply({ name: 'apply' }, [‘Hello']); // Hello, apply • this Λࢦఆͯؔ͠਺Λ࣮ߦͰ͖Δɻ • call ͸ॱ൪ʹҾ਺Λࢦఆ͢Δɻapply ͸Ҿ਺Λ഑ྻͰ౉ͤΔɻ
  13. 5. ଞͷਓʹ࣮ߦΛ·͔ͤΔ var header = { init: function(selector) { this.el

    = $(selector); this.el.find('.show-button').on('click', function(e) { this.showModal(); }); this.el.find('.hide-button').on('click', function(e) { this.hideModal(); }); }, showModal: function() { /* Show modal */ }, hideModal: function() { /* Hide modal */ } }; header.init('.header'); • ଞͷਓ࣍ୈɾɾɾ͓ͦΒ͘ 2 ͔ 4ɻ2ʢάϩʔόϧʣͩͱେมʂ • DOM ͷΠϕϯτϦεφʔͷ৔߹ɺthis ͸ΠϕϯτΛൃՐͨ͠ DOM ཁૉɻ
  14. ରࡦ this.el.find(‘.show-button’).on('click', this.showModal.bind(this)); this.el.find(‘.hide-button').on('click', this.hideModal.bind(this)); • ม਺ʹ this ΛೖΕ͓͍ͯͯɺม਺Λ࢖͏ɻself, that,

    _this ͳͲ͕Α͘࢖ΘΕΔɻ var self = this; this.el.find('.show-button').on('click', function(e) { self.showModal(); }); this.el.find('.hide-button').on('click', function(e) { self.hideModal(); }); • Function.prototype.bind Ͱ this Λࢦఆͨؔ͠਺Λ࡞ΔɻIE9 Ҏ߱Ͱ࢖͑Δ͕ PhantomJS Ͱ࢖͑ͳ͍ͷͨΊɺCI Ͱཁ஫ҙɻes5-shim ͳͲΛೖΕΕ͹࢖͑ΔΑ͏ʹͳΔɻ
  15. ·ͱΊ 1. ϝιουݺͼग़͠: obj.func() -> obj 2. ؔ਺ݺͼग़͠: func() ->

    άϩʔόϧΦϒδΣΫτʢwindow) • strict mode ͳΒ undefined 3. ίϯετϥΫλݺͼग़͠: new Func() -> Πϯελϯε 4. call, apply: func.call(obj), func.apply(obj) -> obj 5. ଞͷਓʹ࣮ߦΛ೚ͤΔ: ΠϕϯτϦεφʔͳͲ -> ଞͷਓͷ࣮૷࣍ୈ