Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JSに不変の愛を

 JSに不変の愛を

We Are JavaScripters! @6th
https://wajs.connpass.com/event/54667/
用の資料です

F425aff2e1f934fc1e5fa95b1f933068?s=128

boiyama

May 01, 2017
Tweet

Transcript

  1. JSʹෆมͷѪΛ ϥϒɾΤόϯδΣϦετࢁຊ͔ΒElmͷ͓༠͍

  2. @boiyaa ෆมͷѪʹṆΕͨஉ

  3. –Adriana Fergerson “JSͷ։ൃऀ͸σϕϩούʔͱ͍͏ΑΓ
 σϕϩούʔπʔϧεϖγϟϦετͩ” ஫ɿ࣮ࡏ͠ͳ͍ਓ෺Ͱ͢

  4. ͱ͍͏͜ͱʹͳΔͷͰ͕͢ɺ͜ͷ࢓༷͕σϕϩούʔπʔ ϧεϖγϟϦετΛੜΈग़͢ཁҼͷҰͭʹͳ͍ͬͯ·͢ɻ const arr = ['foo', 'bar']; arr.push('baz'); console.log(arr); //

    ['foo', 'bar', 'baz'] const obj = { a: 'foo', b: 'bar' }; obj.c = 'baz'; console.log(obj); // { a: 'foo', b: 'bar', c: 'baz' } JSͷObjectܕͷ஋͸Մมʹͳ͍ͬͯ·͢ɻ
 ഑ྻ΍ΦϒδΣΫτ͸ObjectܕͳͷͰɺ
  5. –Anthony Howard “Մม஋͕σόοάΛେมʹ͢Δ” ஫ɿ࣮ࡏ͠ͳ͍ਓ෺Ͱ͢

  6. ͘͝γϯϓϧͳΞϓϦέʔγϣϯΛྫʹΈ͍͖ͯ·͠ΐ͏
 ·ͣɺҎԼͷΑ͏ͳFlux෩ͷը໘ඳըؔ਺Λ࡞Γ·ͨ͠ɻ // ͜ͷؔ਺͸ɺΞϓϦέʔγϣϯͷঢ়ଶͷॳظ஋ modelɺReactίϯϙʔωϯτ Viewɺঢ়ଶߋ৽ؔ਺ update
 // Λड͚औͬͯɺͦΕΛ࢖ͬͯը໘ඳըͱঢ়ଶ؅ཧΛ͠·͢
 function

    program(id, { model, View, update }) {
 // ΞϓϦέʔγϣϯͷঢ়ଶ
 let _model = model 
 render() // ߋ৽ϝοηʔδ msgΛड͚औΓɺঢ়ଶΛߋ৽ͯ͠ඳը͢Δؔ਺
 function dispatch(msg) {
 _model = update(msg, _model)
 render()
 } // ίϯϙʔωϯτʹঢ়ଶͱdispatchؔ਺Λ౉ͯ͠ඳը function render() { ReactDOM.render(<View model={_model} dispatch={dispatch} />, document.getElementById(id)) } }
  7. ͜ΕΛ࢖ͬͯɺ
 ςΩετΛૹ৴͢Δ ͱҰཡʹ௥Ճ͞ΕΔ ؆୯ͳϑΥʔϜΛ࡞ͬ ͯΈ·͢ɻ ©seanmcgrath

  8. ΞϓϦέʔγϣϯͷঢ়ଶͷॳظ஋ // ೖྗ஋valueɺ౤ߘϦετposts const model = { value: "", posts:

    [] }
  9. Reactίϯϙʔωϯτ function View({ model, dispatch }) { return ( <div>

    <div> <input value={model.value} onInput={(e) => dispatch(changeValue(e.target.value))} /> <button onClick={() => dispatch(send())}>Send</button> </div> <ul> {model.posts.map((post, key) => (<li key={key}>{post}</li>))} </ul> </div> ) }
  10. ߋ৽ϝοηʔδੜ੒ؔ਺ function changeValue(value) { return { type: "ChangeValue", value }

    } function send() { return { type: "Send" } }
  11. ঢ়ଶߋ৽ؔ਺ function update(msg, model) { switch (msg.type) { case "ChangeValue":

    { model.value = msg.value return model } case "Send": { model.posts.push(model.value) model.value = "" return model } } }
  12. ςετ͸௨͍ͬͯΔͱ͠·͢ assert.deepEqual( update({ type: "ChangeValue", "foo" }, { value: "",

    posts: [] }), { value: "foo", posts: [] } ); // pass assert.deepEqual( update({ type: "Send" }, { value: "bar", posts: [] }), { value: "", posts: ["bar"] } ); // pass
  13. Ͱ͸programΛ࣮ߦͯ͠Έ·͠ΐ͏ɻ program("form1", { model, View, update })

  14. ࣮ߦ݁Ռ: https://jsbin.com/kepahij/edit?js,output ͜Ε͸ҙਤͨ͠ಈ࡞Λ͍ͯ͠Δͱ͠·͢ɻ
 Ͱ͸ɺ΋͏Ұͭಉ͡ϑΥʔϜΛ௥Ճͯ͠Έ·͢ɻ program("form2", { model, View, update })

    ©Corey Ann
  15. ࣮ߦ݁Ռ: https://jsbin.com/wiseguz/edit?js,output ͢Δͱࠓ౓͸͓͔͠ͳڍಈΛ͢ΔΑ͏ʹͳΓ·ͨ͠ɻ
 ยํͷϑΥʔϜΛૹ৴͢Δͱɺͳ͔ͥ΋͏ยํͷϑΥʔϜ ʹ΋Өڹͯ͠͠·͍·͢Ͷɻ modelʹՄมͰ͋ΔΦϒδΣΫτΛ࢖༻͍ͯͯ͠ɺ͔ͭ program͔Βmodelͷࢀর͕ͦͷ··updateʹ౉͞Ε͍ͯͯɺ
 ͦΕΛมߋͯ͠͠·͏࣮૷ʹͳ͍ͬͯΔ͔ΒͰ͢Ͷɻ ©caleb.wrestle

  16. ͜ͷ৔߹͸Objectͷ஋Λίϐʔ͢Δඞཁ͕͋Γ·ͨ͠ɻ case "ChangeValue": { model.value = msg.value return model }

    ↓ case "ChangeValue": { return { ...model, value: msg.value } }
  17. ͜ͷΑ͏ʹɺՄม஋Λ࢖͏ͱɺؔ਺ͷೖग़ྗͷς ετͰ͸௨͍ͬͯͳ͕Βɺ૝ఆ֎ͷڍಈΛ͢ΔՄ ೳੑ͕͋ΔͷͰɺݪҼΛಥ͖ࢭΊΔʹ͸σόοά Λ͢Δ͜ͱʹͳΓ·͢ɻ ࣮ࡍͷΞϓϦέʔγϣϯ͸ ΋ͬͱෳࡶͳͷͰσόοά ͕େมͳΜͰ͢Ͷɻ ©Vincent Tsui Photography

  18. –Katherine Neuman “զʑ͸ෆมͷѪʹٌ͍͑ͯΔ” ஫ɿ࣮ࡏ͠ͳ͍ਓ෺Ͱ͢

  19. ͱ͍͏Θ͚Ͱɺෆม஋Λ ࡞Δʹ͸৭ʑͳํ๏͕͋ Γ·͢ɻ • Immutable.jsΛ࢖͏ • Object.freeze()Λ࠶ؼ తʹ͔͚Δ • Flowͷڞม΍ɺ

    TypeScriptͷreadonlyΛ ར༻͢Δ
  20. –Freddie Boyle “JS͸஋Λଋറ͢Δ͜ͱ͸Ͱ͖ͯ΋ɺ
 զʑΛଋറ͢Δ͜ͱ͸Ͱ͖ͳ͍” ஫ɿ࣮ࡏ͠ͳ͍ਓ෺Ͱ͢

  21. ͔͠͠ɺ ͦΜͳίʔσΟϯάϧʔϧΛ࡞ͬͯ΋
 ࣌ʹաͪΛ൜ͯ͠͠·͏ͷ͕ਓؒͰ͢ɻ ෆม஋͸࡞Ζ͏ͱ͠ͳ͚Ε͹࡞Εͳ͍ͷͰɺ
 ؒҧ͑ͯ๨ΕΔ͜ͱ͕͋Γ·͢ɻ ͦ͜Ͱɺͥͻ͓͢͢Ί͍ͨ͠AltJS͕͋Γ·͢ɻ ©Corey Ann

  22. –Jennifer Comer “ਓྨΑɺ͜Ε͕Elmͩ” ஫ɿ࣮ࡏ͠ͳ͍ਓ෺Ͱ͢

  23. Elmͱ͸ɺશͯͷܕ͕ෆมͷɺ
 ΠϛϡʔλϒϧɾϥϒʹຬͪᷓΕͨݴޠͰ͢ɻ ͲΜͳγϯλοΫεͳͷ͔ɺ ͖͞΄ͲͷΞϓϦέʔγϣ ϯΛElmʹҠ২͠ͳ͕ΒΈ ͍͖ͯ·͠ΐ͏

  24. const model = { value: "", posts: [] } model

    = { value = "", posts = [] } ͜ͷΦϒδΣΫτͬΆ͍ͷ͸Recordͱݴ͍·ͯ͠ɺ ΄΅ΦϒδΣΫτͷΑ͏ʹ࢖͑·͢ Πϛϡʔλϒϧɾϥϒɺ஫ೖ
  25. function View({ model, dispatch }) { return ( <div> <div>

    <input value={model.value} onInput={(e) => dispatch(changeValue(e.target.value))} /> <button onClick={() => dispatch(send())}>Send</button> </div> <ul> {model.posts.map((post, key) => (<li key={key}>{post}</li>))} </ul> view model = div [] [ div [] [ input [ value model.value, onInput ChangeValue ] [] , button [ onClick Send ] [ text "Send" ] ] , ul [] (map (\post -> li [] [ text post ]) model.posts) ] ม਺ͬΆ͍Ͱ͕ؔ͢਺Ͱ͢ɻElmʹ͸ม਺͕͋Γ·ͤΜɻ `foo = bar`͸`var foo = bar`Ͱ͸ͳͯ͘`function foo() { return bar }`Ͱɺ `foo bar = bar ++ baz`͸`function foo(bar) { return bar + baz }`Ͱ͢
  26. function changeValue(value) { return { type: "ChangeValue", value } }

    function send() { return { type: "Send" } } type Msg = ChangeValue String | Send ͜Ε͸ϢχΦϯܕͱݴ͍·ͯ͠ɺ ܕ = ίϯετϥΫλ | ίϯετϥΫλ | ...ͱఆٛ͠·͢ɻ ίϯετϥΫλ͸ؔ਺ͱͯ͠࢖༻Ͱ͖·͢ɻ ͜͜Ͱ͸ߋ৽ϝοηʔδͱͯ͠࢖༻͠ɺ view͔Βupdateʹ౉͍ͯ͠·͢ɻ
  27. function update(msg, model) { switch (msg.type) { case "ChangeValue": {

    model.value = msg.value return model } case "Send": { model.posts.push(model.value) model.value = "" return model } update msg model = case msg of ChangeValue value -> { model | value = value } Send -> { value = "", posts = (model.posts ++ [ model.value ]) } Ϩίʔυͷߋ৽ํ๏͸͜Μͳײ͡Ͱɺ ৽͍͠ϨίʔυΛฦ͠·͢ɻ
  28. ࣮ߦ݁Ռ:
 https://ellie-app.com/38FyY8FKKX7a1/0 ©c non ͜ͷΑ͏ʹ஋ͷॲཧʹؾΛ࢖ Θͣʹ෭࡞༻ͷͳ͍ΞϓϦέʔ γϣϯ͕࡞Ε·ͨ͠ɻ ݴޠϨϕϧͰෆมͩͱɺͲ͜ ͔ͷॲཧ͕Ͳ͔͜ͷ஋Λมߋ ͯ͠͠·͏͜ͱ͕ઈରʹͳ͍

    ͱ͍͏҆৺ײ͕͋Γ·͢Ͷɻ
  29. ڧ͍੩తܕ෇͚Ͱɺ NullͱUndefined͕ ແ͍ɺͱ͍͏ಛ௃΋ ͋ΓɺϥϯλΠϜΤ ϥʔ͕ى͖ͳ͍ͱ͍ ͏ϝϦοτ΋͋Γ· ͢ɻ ςετͱίϯύΠϧ ͕௨ΔͳΒɺΞϓϦ έʔγϣϯ͸ظ଴௨

    ΓͷৼΔ෣͍Λ͢Δ ͱ͍͏ͷ͕Elmͷັ ྗͰ͢Ͷɻ ©sapex
  30. Elm - A delightful language for reliable webapps http://elm-lang.org/ ©Vincent

    Tsui Photography
  31. Thank you for loving me