Swift で JavaScript 始めませんか? #iOSDC

-- Views

August 20, 16

スライド概要

Swift ランタイムで簡単に JavaScript を実行できる JavaScriptCore を Swift で使うための基礎のお話です。Swift と JavaScript の相互運用が簡単にできて面白いです。この資料は 2016/08/20 に iOSDC 2016 で発表したものになります。

※ Docswell での公開に移行する直前の Slideshare での閲覧数は 10,093 でした。

profile-image

正統派趣味人プログラマー。プログラミングとは幼馴染です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

4XJGU Ͱ +BWB4DSJQU ࢝Ί·ͤΜ͔ʁ J04%$PO"VHVTU UI &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ 4XJGU%FWFMPQFS1SFWJFX

2.

Έͳ͞Μ +BWB4DSJQU͸޷͖Ͱ͔͢ʁ

3.

+BWB4DSJQU ྑ͍Ͱ͢ΑͶʂ

4.

+BWB4DSJQU ίʔυͷงғ‫ؾ‬ for (var index in lines) { var line = lines[index]; var itemContent; if (line.match(expression)) { itemContent = RegExp.$2; } var outputItem = core.escapeHtml(itemContent); return outputItems.map(convertToTag).join('\n'); } +BWB4DSJQU

5.

+BWB4DSJQU͕4XJGU͔Β࢖͑Δʂ

6.

8,8FC7JFX

7.

+BWB4DSJQU$PSF GSBNFXPSL

8.

‫۽‬୩༑޺ 5PNPIJSP,VNBHBJ ⾣ 4XJGU‫͕ޠݴ‬௒େ޷͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษ‫ڧ‬ձ͕େ޷͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ఻͍͖͍͑ͯͨɻ !FT@LVNBHBJ UPNPIJSPLVNBHBJ $PEF1JFDFGPSNBD04 IUUQF[OFUKQ 9DPEFపఈղઆ

9.

ษ‫ڧ‬ձΛ։࠵͍ͯ͠·͢ɻ Θ͍Θ͍ɺָ͘͠ɺ ΈΜͳͰ‫ޠ‬Β͑Δ৔ॴΛ໨ࢦͯ͠ɻ ԣ඿J1IPOF։ൃऀษ‫ڧ‬ձ ΧδϡΞϧ4XJGUษ‫ڧ‬ձ ZJEFW ˏԣ඿ɾഅंಓ DTXJGU !ԣ඿ɾ੨༿୆ ୈճ໨͸݄೔ͷ։࠵ʢ໨ඪʣ IUUQTBUOEPSHHSPVQTZJEFW ୈճ໨Λ݄̏̕೔ʹ։࠵ IUUQTBUOEPSHHSPVQTDTXJGU

10.

΋͏ͻͱͭɺษ‫ڧ‬ձΛ࢝Ί·͢ʂ 4XJGUͷ‫ૅج‬ΛΈΜͳͱ෮श͍ͨ͠ɻ ͜Ε͔Β࢝ΊΔਓͱ΋௒্‫ͱऀڃ‬΋Ұॹʹɻ ΈΜͳͰ4XJGU ෮शձ NJOOB@EF@TXJGU ˏौ୩ ୈճ໨Λ݄೔ʹ։࠵ IUUQDTXJGUDPOOQBTTDPN

11.

ωοτϥδΦ Ќ์ૹ։࢝ ϓϩάϥϛϯά͕େ޷͖ͳ̎ਓͰɺ ϓϩάϥϜ‫ޠָ͍ͯͭ͘͠ʹޠݴ‬Β͏൪૊ NPPLNPPLSBEJP Ќ൛ ‫۽‬୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ಺͔Β ௌ͑ͯ͘͜Δ੠ʹࣖΛ܏ָ͚ͯ͠ΉϥδΦ IUUQNPPLNPPLSBEJPDPNB

12.

$PEF1JFDFGPSNBD04 ษ‫ڧ‬ձΛָ͠ΉΞϓϦ ⾣ ιʔείʔυΛ5XJUUFSͱ(JTUʹಉ࣌౤ߘ ⾣ ίʔυཝΛۭʹ͢Ε͹ɺී௨ʹπΠʔτՄೳ ⾣ ϋογϡλάΛઃఆͰ͖Δʗ෇͚๨Εͳ͍ #iOSDC

13.

4XJGUͰ+BWB4DSJQU ࢝Ί·ͤΜ͔ʁ

14.

͸͡Ίʹ +BWB4DSJQUͱ͍͑͹ ⾣ खܰʹॻ͚ΔεΫϦϓτ‫ޠݴ‬ ⾣ ೥ʹొ৔ ⾣ ొ৔͔࣌Βࠓ೔·Ͱ8FCํ໘Ͱ‫׆‬༂ ⾣ +BWB4DSJQUΛॻ͚Δਓͬͯଟ͍͸ͣ

15.

͸͡Ίʹ +BWB4DSJQU$PSFͱ͍͑͹ ⾣ +BWB4DSJQUΛ࣮ߦͰ͖Δ‫ڥ؀‬ ⾣ ίʔυ͸ϥϯλΠϜͰධՁ ⾣ 4XJGUͱͷ૬‫ޓ‬ӡ༻͕؆୯ʹͰ͖Δ

16.

͸͡Ίʹ +BWB4DSJQU$PSFͷΠϝʔδ 4XJGU 0CKFDUJWF$3VOUJNF +47JSUVBM.BDIJOF PCKD +4$POUFYU 関数 ؔ਺ ؔ਺ クラス型 ΦϒδΣΫτ ΦϒδΣΫτ 変数 ม਺ ม਺ 文字列 変数 Ç㲋 Ç㲋 +BWB4DSJQUίʔυ ม਺

17.

͸͡Ίʹ +BWB4DSJQU$PSFͷ࢖༻ྫ ⾣ ࠶Ϗϧυͤͣʹ࣮૷Λࠩ͠ସ͑Δ ⾣ ΞϓϦͷಈ࡞ΧελϚΠζͷͨΊͷ ΧελϜεΫϦϓτ‫ڥ؀‬Λఏ‫͖Ͱڙ‬Δ ⾣ +BWB4DSJQUίʔυΛ࢖ͬͯ ωΠςΟϒΞϓϦΛ੍‫͖Ͱޚ‬Δ ⾣ 8FC‫ܦ‬༝ͰΞϓϦͷ࣮૷Λมߋ͢Δ

18.

4XJGUͰ+BWB4DSJQU ࢖ͬͯΈͨ͘ͳΓ·͔ͨ͠ʁ

19.

Ͱ΋·ͬͯ ͪΐͬͱ‫͍ͳ͗͢ྗڧ‬ʁ

20.

ΞϓϦ৹ࠪ͸௨Δͷʁ

21.

΄Μͱ͢Έ·ͤΜ ˚A ͥΜͥΜߟ͑ͯ·ͤΜͰͨ͠ 2"Ͱ‫ͨ͠·͖͍ͩͨͯ͑ڭ‬ʂ ͪΌΜͱ৹ࠪ௨ΔΈ͍ͨʁ͋Γ͕ͱ͏͍͟͝·͢ʂ

22.

͸͡Ίʹ +BWB4DSJQU$PSF ಈ࡞‫ڥ؀‬ ⾣ J04Ҏ্ ⾣ NBD04.BWFSJDLTҎ্ ⾣ UW04Ҏ্ ެࣜจॻ "1*3FGFSFODF+BWB4DSJQU$PSF IUUQTEFWFMPQFSBQQMFDPNSFGFSFODFKBWBTDSJQUDPSF

23.

4XJGUͰ+BWB4DSJQU ࢖ͬͯΈͨ͘ͳΓ·͔ͨ͠ʁ

24.

+BWB4DSJQU$PSF ‫ج‬ຊతͳ࢖͍ํ

25.

+BWB4DSJQU$PSFͷ‫ج‬ຊ ཁॴ  +BWB4DSJQU$PSFΛΠϯϙʔτ͢Δ  +4$POUFYUΛੜ੒͢Δ  +BWB4DSJQUίʔυΛ࣮ߦ͢Δ  ม਺ͷ஋Λ4XJGUͰऔಘ͢Δ  ࣮ߦͱ݁ՌऔಘΛಉ࣌ʹߦ͏

26.

+BWB4DSJQU$PSFͷ‫ج‬ຊ  +BWB4DSJQU$PSFΛΠϯϙʔτ͢Δ ⾣ +BWB4DSJQU$PSFϞδϡʔϧΛ࢖͏ ⾣ ී௨ʹJNQPSUߏจͰΠϯϙʔτ͢Δ import JavaScriptCore 4XJGUCFUB

27.

+BWB4DSJQU$PSFͷ‫ج‬ຊ  +4$POUFYUΛੜ੒͢Δ ⾣ ίϯςΩετͰঢ়ଶΛ؅ཧ͢Δ ⾣ ෳ਺ͷίϯςΩετΛ࡞Δ͜ͱ΋Մೳ let context = JSContext()! 4XJGUCFUB

28.

+BWB4DSJQU$PSFͷ‫ج‬ຊ  +BWB4DSJQUίʔυΛ࣮ߦ͢Δ ⾣ ίϯςΩετʹ+BWB4DSJQUίʔυΛૹΔ ⾣ ίʔυ͸4USJOH‫ܕ‬ͷσʔλͰ࡞Δ context.evaluateScript("var v1 = 10") context.evaluateScript("var v2 = 20") context.evaluateScript("var v3 = v1 + v2") 4XJGUCFUB

29.

+BWB4DSJQU$PSFͷ‫ج‬ຊ  ม਺ͷ஋Λ4XJGUͰऔಘ͢Δ ⾣ 4XJGUଆͰ+47BMVF‫ܕ‬ͷ஋ͱͯ͠औಘͰ͖Δ ⾣ ଘࡏ͠ͳ͍৔߹͸VOEFpOFEͱͯ͠ಘΒΕΔ let value = context.objectForKeyedSubscript("v3")! print("Answer = ", value) // Answer = 30 // 指定した名前が存在しない場合は undefined let value = context.objectForKeyedSubscript("vX")! print("Answer = ", value) // Answer = undefined 4XJGUCFUB

30.

+BWB4DSJQU$PSFͷ‫ج‬ຊ  ࣮ߦͱ݁ՌऔಘΛಉ࣌ʹߦ͏ ⾣ FWBMVBUF4DSJQUϝιου͸+47BMVFΛฦ͢ ⾣ ධՁ݁ՌΛ௚઀4XJGUͰड͚औΕΔ let answer = context.evaluateScript("v1 + v2") 4XJGUCFUB

31.

4XJGU͔Β+BWB4DSJQUΛ εϚʔτʹ࣮ߦͰ͖ͯɺ‫͍͠خ‬

32.

+BWB4DSJQU$PSF ม਺ͷѻ͍ํ

33.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  +47BMVFͰද‫͢ݱ‬Δ ⾣ +BWB4DSJQUͷ஋͸+47BMVF‫Ͱܕ‬ѻ͏ ⾣ ͍ΖΜͳछྨͷ஋ΛऔΓѻ͑Δ let value: JSValue 4XJGUCFUB

34.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  +47BMVFΛ4XJGU‫ʹܕ‬ม‫͢׵‬Δ ⾣ +47BMVF͔Β4XJGU‫ܕ‬ͷ஋ΛऔಘͰ͖Δ ⾣ UP5ZQFOBNFϝιουΛ࢖͏ • toInt32() -> Int32 • toUInt32() -> UInt32 • toDouble() -> Double • toNumber() -> NSNumber! • toString() -> String! • toBool() -> Bool! • toObject() -> Any! • toDate() -> Date! -> [Any]! • toArray() • toDictionary() -> [AnyHashable : Any]! 4XJGUCFUB

35.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  +47BMVFͷछྨΛ൑ఆ͢Δ ⾣ +BWB4DSJQUతʹͲΜͳ‫Ͱ͔ܕ‬൑ఆ͢Δ ⾣ JT5ZQFOBNFϓϩύςΟΛ࢖͏ • isNumber • isString • isBoolean • isObject • isUndefined • isNull • isArray • isDate 4XJGUCFUB

36.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  4XJGUͰͷVOEFpOFEͷѻ͍ ⾣ ͍ΘΏΔ;&30ͱͯ͠ѻΘΕΔ͜ͱ͕ଟ͍ • toInt32() → 0 • toUInt32() → 0 • toDouble() → nan • toBool() → false → nil • toObject() → nil • toArray() • toDictionary() → nil → nan • toNumber() • toString() → "undefined" • toDate() → -5877520-03-03 -596:-31:-23 +0000 • toDate().timeIntervalSince1970 → nan • toNumber().intValue → -9223372036854775808 • toNumber().uintValue → 9223372036854775808 4XJGUCFUB • toNumber().doubleValue → nan

37.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  4XJGUͰͷOVMMͷѻ͍ ⾣ ͍ΘΏΔ;&30ͱͯ͠ѻΘΕΔ • toInt32() → 0 • toUInt32() → 0 • toDouble() → 0.0 • toBool() → false → nil • toObject() → nil • toArray() • toDictionary() → nil → 0 • toNumber() • toString() → "null" • toDate() → 1970-01-01 00:00:00 +0000 • toDate().timeIntervalSince1970 → 0 • toNumber().intValue → 0 • toNumber().uintValue → 0 4XJGUCFUB • toNumber().doubleValue → 0.0

38.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  +47BMVFͰΦϒδΣΫτΛૢ࡞͢Δ ⾣ +BWB4DSJQUΦϒδΣΫτΛ4XJGUͰ࢖͑Δ ⾣ ϓϩύςΟ΋ϝιου΋ར༻Մೳ let article: JSValue = context.evaluateScript("article")! // プロパティの参照 let title = article.forProperty("title") // JavaScript メソッドの実行 let note = article.invokeMethod("getDescription", withArguments: []) 4XJGUCFUB

39.

+BWB4DSJQU$PSFͷม਺ʹ͍ͭͯ  +47BMVF͸ൺֱͰ͖Δ ⾣ +47BMVF‫ܕ‬͸ԋࢉࢠͰൺֱͰ͖Δ ⾣ ‫ܧ‬ঝ‫ݩ‬ͷ/40CKFDU͕&RVBUBCMFʹ४‫͍ͯ͠ڌ‬Δ let value1: JSValue = context.objectForKeyedSubscript("v1")! let value2: JSValue = context.objectForKeyedSubscript("v2")! if value1 == value2 { } 4XJGUCFUB

40.

ม‫ͳࡏࣗݬ‬+BWB4DSJQUม਺Λ ΦϒδΣΫτ΋‫ؚ‬ΊͯૢΕΔͷɺྑ͍

41.

+BWB4DSJQU$PSF +BWB4DSJQU"1*

42.

+BWB4DSJQU$PSFͷ+BWB4DSJQU"1* ૊ΈࠐΈͷ"1* ⾣ ‫ج‬ຊతͳ૊ΈࠐΈ‫ػ‬ೳ͚͕ͩ࢖͑Δ ⾣ %0.ͳͲͷಛผͳ‫ػ‬ೳ͸උΘ͍ͬͯͳ͍ • Object • Array • Date • Math • RegEx • JSON • Error ʜ • parseInt • parseFloat • encodeURI • decodeURI • encodeURIComponent • decodeURIComponent • encodeURI • eval • escape +BWB4DSJQU

43.

γϯϓϧͳ‫ʹڥ؀‬ ࣗ෼ͷखͰ"1*Λߏங͢Δ

44.

+BWB4DSJQU"1*ͷߏங ࣮‫ํݱ‬๏ ⾣ +4$POUFYUʹ"1*Λ௥Ճ͢Δ ⾣ ࣍ͷΑ͏ͳํ๏Ͱ‫ػ‬ೳΛఏ‫͖Ͱڙ‬Δ " ม਺Λ+BWB4DSJQU͔Βఏ‫͢ڙ‬Δ # ม਺Λ4XJGU͔Βఏ‫͢ڙ‬Δ $ ؔ਺Λ+BWB4DSJQU͔Βఏ‫͢ڙ‬Δ % ؔ਺Λ4XJGU͔ΒऔΓࠐΜͰఏ‫͢ڙ‬Δ & +BWB4DSJQU͔ΒΦϒδΣΫτΛఏ‫͢ڙ‬Δ ' 4XJGUͷ‫ܕ‬Λ+BWB4DSJQUʹ௚઀ఏ‫͢ڙ‬Δ

45.

+BWB4DSJQU"1*ͷߏஙํ๏  ม਺ Λ+BWB4DSJQUͰఆٛ͢Δ ⾣ ม਺Λఆٛ͢Δ+BWB4DSJQUΛ࣮ߦ͢Δ ⾣ Ҏ߱ɺίϯςΩετ಺Ͱ͜ͷม਺͕࢖͑Δ context.evaluateScript("var timeout = 5.0") 4XJGUCFUB

46.

+BWB4DSJQU"1*ͷߏஙํ๏  ม਺ Λ4XJGU͔Βఆٛ͢Δ ⾣ 4XJGUͷม਺஋ΛίϯςΩετʹઃఆ͢Δ ⾣ ஋‫ͳܕ‬Βෳ੡͞Εɺࢀর‫ͳܕ‬Β‫ڞ‬༗͞ΕΔ let account = "@es_kumagai" // Swift 変数 account を、JavaScript に変数 name で登録 context.setObject(account, forKeyedSubscript: "name" as NSString) 4XJGUCFUB͸Ωϟετ͕ඞཁ ͦͷ͏ͪɺඞཁͳ͘ͳΔ͸ͣ 4XJGUCFUB

47.

+BWB4DSJQU"1*ͷߏஙํ๏  ؔ਺ Λ+BWB4DSJQUͰఆٛ͢Δ ⾣ ؔ਺Λఆٛ͢Δ+BWB4DSJQUΛ࣮ߦ͢Δ ⾣ Ҏ߱ɺίϯςΩετ಺Ͱ͜ͷؔ਺͕࢖͑Δ context.evaluateScript( "function getAttribute(name) {" + " return attributes[name];" + "}") 4XJGUCFUB

48.
[beta]
+BWB4DSJQU"1*ͷߏஙํ๏ 

ؔ਺ Λ4XJGU͔ΒऔΓࠐΉ
⾣ 4XJGUͷΫϩʔδϟʔΛίϯςΩετʹઃఆ͢Δ
⾣ !DPOWFOUJPO CMPDL Λࢦఆͯ͠"OZ0CKFDUͰѻ͏

let output : @convention(block) (String) -> Void = {
NSLog("\(account) : \($0)")
}
// クロージャーを AnyObject 型にキャストして登録

context.setObject(
unsafeBitCast(output, to: AnyObject.self),
forKeyedSubscript: "output" as NSString)
4XJGUCFUB

49.

+BWB4DSJQU"1*ͷߏஙํ๏  +BWB4DSJQUͰΦϒδΣΫτΛఆٛ͢Δ ⾣ ΦϒδΣΫτΛఆٛ͢Δ+BWB4DSJQUΛ࣮ߦ͢Δ ⾣ Πϯελϯε͸4XJGUͰ΋࢖͑Δ context.evaluateScript( "function Article(title, body) {" + " this.title = title;" + " this.body = body;" + "}" + "" + "Article.prototype.getDescription = " + " function() {" + " return this.body.substr(0, 10);" + "};") 4XJGUCFUB

50.
[beta]
+BWB4DSJQU"1*ͷߏஙํ๏ 

4XJGUͷ ‫ ܕ‬Λ+BWB4DSJQUͰ࢖͏ 
⾣ +BWB4DSJQUͰ࢖͏"1*ΛϓϩτίϧͰఆٛ͢Δ
⾣ ϓϩτίϧ͸!PCKDΛࢦఆɺ+4&YQPSUΛ‫ܧ‬ঝ͢Δ

@objc protocol ImageInterface : JSExport {
var width: Int { get set }
var height: Int { get set }
// インスタンス化をしたい場合は静的メソッドも宣言

static func make(name: String, scale: CGFloat)
-> AnyObject
}
4XJGUCFUB

51.
[beta]
+BWB4DSJQU"1*ͷߏஙํ๏ 

4XJGUͷ ‫ ܕ‬Λ+BWB4DSJQUͰ࢖͏ 
⾣ +BWB4DSJQUͰ࢖͏‫ܕ‬Λఆٛ͢Δ
⾣ +4&YQPSU४‫ڌ‬ͷϓϩτίϧͱ/40CKFDUΛ‫ܧ‬ঝ͢Δ

class Image : NSObject, ImageInterface {
var width, height: Int
required init(name: String, scale: CGFloat) {…}
class func make(name: String, scale: CGFloat)
-> AnyObject {
return self.init(name: name, scale: scale)
}

4XJGUCFUB

52.

+BWB4DSJQU"1*ͷߏஙํ๏  4XJGUͷ ‫ ܕ‬Λ+BWB4DSJQUͰ࢖͏  ⾣ ΠϯελϯεΛ࢖͏͚ͩͳΒม਺Ληοτ͢Δ ⾣ ϓϩτίϧͰ໌‫"ͨ͠ه‬1*͚͕ͩ࢖͑Δ let image = Image(name: "Profile", scale: 0.8) context.setObject(image, forKeyedSubscript: "icon" as NSString) 4XJGUCFUB

53.

+BWB4DSJQU"1*ͷߏஙํ๏  4XJGUͷ ‫ ܕ‬Λ+BWB4DSJQUͰ࢖͏  ⾣ ΠϯελϯεΛੜ੒͍ͨ͠ͳΒ‫ܕ‬৘ใΛηοτ͢Δ ⾣ ੩తϝιου‫ܦ‬༝ͰΠϯελϯεΛੜ੒Ͱ͖Δ context.setObject(Image.self, forKeyedSubscript: "Image" as NSString) // メソッドは、全てのラベルを名前に含めて実行すること context.evaluateScript( "var banner = " + "Image.makeWithNameScale('picture', 0.5)") 4XJGUCFUB

54.

4XJGUͷ‫ػ‬ೳΛͦͷ·· +BWB4DSJQUʹఏ‫͖Ͱڙ‬Δͷɺૉ੖Β͍͠

55.

+BWB4DSJQU$PSF ίʔυΛॻ͖΍͘͢

56.

+BWB4DSJQUΛॻ͖΍͘͢͢Δ จࣈྻʹຒΊࠐΉͷ͸໘౗ ⾣ ͜ͷॻ͖ํͩͱɺͱͯ΋ಡΈʹ͍͘ ⾣ ίʔυΛॻ͘ͷ͕ࠔ೉ʹͳΓ͕ͪ context.evaluateScript( "function Article(title, body) {" + " this.title = title;" + " this.body = body;" + "}" + "" + "Article.prototype.getDescription = " + " function() {" + " return this.body.substr(0, 10);" + "};") 4XJGUCFUB

57.

+BWB4DSJQUΛ ผϑΝΠϧʹॻ͖ग़͢

58.

+BWB4DSJQUΛॻ͖΍͘͢͢Δ  +4ϑΝΠϧΛొ࿥͢Δ ⾣ +BWB4DSJQUίʔυΛKTϑΝΠϧͰ༻ҙ͢Δ ⾣ ΞϓϦʹόϯυϧͯ͠࢖͏ 9DPEF

59.

+BWB4DSJQUΛॻ͖΍͘͢͢Δ  +4ϑΝΠϧʹίʔυΛॻ͘ ⾣ ιʔείʔυΤσΟλʔͰฤूͰ͖Δ ⾣ ϋΠϥΠτදࣔ΍ɺ͋Δఔ౓ͷίʔυิ‫͕׬‬ར͘ 9DPEF

60.

+BWB4DSJQUΛॻ͖΍͘͢͢Δ  +4ϑΝΠϧΛಡΈࠐΜͰ࢖͏ ⾣ +4ϑΝΠϧ͔ΒίʔυΛಡΈࠐΉ ⾣ ಡΈࠐΜͩίʔυΛ࣮ߦ͢Δ let path = Bundle.main.url( forResource: "JavaScriptAPI", withExtension: "js")! let source = try! String(contentsOf: path) // 読み込んだ JavaScript をコンテキストで実行 let context = JSContext()! context.evaluateScript(source) 4XJGUCFUB

61.

จࣈྻϦςϥϧͰ͸ͳ͘ ૉͷίʔυͰॻ͚ΔͱɺḿΔ

62.

+BWB4DSJQU$PSFGSBNFXPSL ·ͱΊ +BWB4DSJQUΛ4XJGU͔Β ؆୯ɾࣗࡏʹѻ͑Δͷ͕‫͍͠خ‬ ⾣ +BWB4DSJQU$PSFͱ͸ ⾣ +BWB4DSJQUίʔυΛ࣮ߦ͢Δ ⾣ +47BMVFΛѻ͏ʢൺֱɺม‫׵‬ɺ൑ఆʣ ⾣ "1*Λఆٛ͢Δʢؔ਺ɺม਺ɺΦϒδΣΫτʣ

63.

4XJGUͰ+BWB4DSJQU ࢝ΊͯΈ·ͤΜ͔ʁ

64.

&OKPZ4XJGU 5IBOLZPV 4XJGUͰ+BWB4DSJQU࢝Ί·ͤΜ͔ʁ &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ ⾣ +BWB4DSJQU$PSFͱ͸ ⾣ +BWB4DSJQUίʔυΛ࣮ߦ͢Δ ⾣ +47BMVFΛѻ͏ʢൺֱɺม‫׵‬ɺ൑ఆʣ ⾣ "1*Λఆٛ͢Δʢؔ਺ɺม਺ɺΦϒδΣΫτʣ