Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
楽しいProxy
Search
Ryo Nakamura
December 20, 2018
Programming
2
120
楽しいProxy
Proxy is so much fun! @We are JavaScripters! #27
Ryo Nakamura
December 20, 2018
Tweet
Share
More Decks by Ryo Nakamura
See All by Ryo Nakamura
やさしい仮想DOM
ryonkmr
1
230
Other Decks in Programming
See All in Programming
2026年 エンジニアリング自己学習法
yumechi
0
130
Patterns of Patterns
denyspoltorak
0
1.4k
CSC307 Lecture 02
javiergs
PRO
1
780
Oxlint JS plugins
kazupon
1
890
Lambda のコードストレージ容量に気をつけましょう
tattwan718
0
120
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
400
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
MUSUBIXとは
nahisaho
0
130
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
170
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.5k
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
190
登壇資料を作る時に意識していること #登壇資料_findy
konifar
4
1.1k
Featured
See All Featured
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.6k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
3.9k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Exploring anti-patterns in Rails
aemeredith
2
250
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.3k
Art, The Web, and Tiny UX
lynnandtonic
304
21k
New Earth Scene 8
popppiees
1
1.5k
The Curse of the Amulet
leimatthew05
1
8.4k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
74
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
160
Producing Creativity
orderedlist
PRO
348
40k
Transcript
RyoNkmr PROJECT DATE PRESENTER 2018-12-20 ָ͍͠Proxy @WE ARE JAVASCRIPTERS! #27
ࣗݾհ • RyoNkmr • @RyoNkmr_ • Retty Inc. • JavaScript
3ੜ • ॳొஃ
ָ͍͠ Proxy
Proxy
...͜ΕΒجຊతͳݴޠૢ࡞ʢྫ ͑ɺϓϩύςΟݕࡧɺೖɺྻ ڍɺؔݺͼग़͠ͳͲʣʹׂΓࠐ Έɺಈ࡞ΛΧελϚΠζͰ͖·͢ɻ [ϝλϓϩάϥϛϯά | MDN](https:// developer.mozilla.org/ja/docs/Web/ JavaScript/Guide/ Meta_programming)
Proxy
ରԠঢ়گ
https://caniuse.com/#search=proxy
https://node.green/#ES2015-built-ins-Proxy
Browser: IE11Ҏ֎ Node: v6.4.0Ҏ߱ ରԠঢ়گ
Proxyͱͷग़ձ͍
ͱ͋Δݱͷ Pull Request { type: Array, validate(values) { return values.length
!== 0; }, }
(ϨϏϡΞʔ) { type: Array, validate(values) { return values.length !== 0;
}, } const fakeData = { length : 1000 }; ͜ΕͰಥഁͰ͖ΔͷͰɾɾɾʁ(Request Changes)
{ type: Array, validate(values) { return Array.isArray(values) && values.length !==
0; }, }
(ϨϏϡΞʔ) { type: Array, validate(values) { return Array.isArray(values) &&
values.length !== 0; }, }
(ϨϏϡΞʔ) const fakeData = new Proxy([], { get(...args) { if
(args[1] === 'length') { return -100000000000; } return Reflect.get(...args); } }); > fakeData.length // -100000000000 > Array.isArray(fakeData) // true ͜ΕͰಥഁͰ͖ΔͷͰɾɾɾʁ(Request Changes) { type: Array, validate(values) { return Array.isArray(values) && values.length !== 0; }, }
{ type: Array, validate(values) { return Array.isArray(values) && values.length >
0; }, }
Proxy
͓ͪΌͰɾɾɾʁ
None
͍ಓΛߟ͑ͯΈΔ
ॲཧΛࠩ͠ࠐΉ
Logger on a Node.js Application
module.exports = new Proxy(console, { get(target, prop, receiver) { return
(...args) => { require('fs').appendFile('logger.log', `[${prop}]: ${args}`, 'utf8', err => { if (err) { throw err; } }); return Reflect.apply(target[prop], receiver, args); }; } }); console Λ Proxy
> const logger = require('./log.js'); > logger.log('plz log me') plz
log me > logger.error('this is an error!') this is an error! > logger.count('cat') cat: 1 > logger.count('dog') dog: 1 > logger.count('cat') cat: 2 console ͱಉ͡ interface
$ cat logger.log [log]: plz log me [error]: this is
an error! [count]: cat [count]: dog [count]: cat ࣮ߦ࣌ʹϑΝΠϧʹॻ͖ग़͢
Get Λ Proxy ͯ͠༡Ϳ
ແݶϝιουνΣʔϯ > https://www.keithcirkel.co.uk/metaprogramming-in-es6- part-3-proxies/
module.exports = (domain = 'google.com') => { let paths =
[]; // ঢ়ଶΛ͓࣋ͬͯ͘ // ঢ়ଶΛݩʹURLจࣈྻΛΈཱͯΔؔͷఆٛ const buildUrl = () => { const _paths = [...paths]; paths = []; return `https://${domain}/${_paths.join('/')}`; }; return new Proxy(buildUrl, { get(_, prop, receiver) { // propertyΞΫηεΛঢ়ଶͷมߋʹ͏ paths = [...paths, prop]; // chaining͢ΔͨΊʹProxyࣗΛฦͯ͋͛͠Δ return receiver; }, }); };
const urlBuilder = require('./urlBuilder.js'); const google = urlBuilder('www.google.co.jp'); > google.image.saikyo.engineer.wannabe();
'https://www.google.co.jp/image/saikyo/engineer/wannabe' > google.search.cool.javascripters(); 'https://www.google.co.jp/search/cool/javascripters' method missing Ά͍͜ͱ͕Ͱ͖Δ
Array Λ Proxy ͯ͠༡Ϳ
Πέϝϯͳ Array
const parsePropName = prefixCool => { const [, name] =
/^cool(\w+)/.exec(prefixCool) || [, null]; return name !== null ? `${name[0].toLowerCase()}${name.slice(1)}` : prefixCool; } module.exports = ({ goodLooking } = { goodLooking: false }) => ( new Proxy([], { get(target, prop, receiver) { const actualPropName = parsePropName(prop); if ( typeof target[actualPropName] !== 'function' || goodLooking || prop.startsWith('cool') ) { return Reflect.get(target, actualPropName, receiver); } throw new TypeError(`Hmm... You'are not my type`); } }) );
> const coolArray = require('./coolArray.js')(); undefined > coolArray.push('hey, man.'); TypeError:
Hmm... You'are not my type at Object.get (.../proxy/coolArray.js:18:13) > coolArray.coolPush('hey, handsome man.'); 1 > [...coolArray.coolValues()]; [ 'hey, handsome man.' ] cool͍͍ͬͯͪͪݴΘͳ͍ͱ ݴ͏͜ͱΛฉ͔ͳ͍ArrayΛ࡞ΕΔ
Proxy ָ͍͠
·ͱΊ
• ґଘίʔυΛͦͷ··ʹɺґଘϥΠϒϥ ϦΛࣅͨΑ͏ͳผʹࠩ͠ସ͑Δͱ͖ • ϥΠϒϥϦͱ͔ϑϨʔϜϫʔΫͭ͘Δͱ ͖ • Array.isArray ͕ true
Λฦ͢ͷʹ length ͩ ͚͓͔͍͠Λฦ͢ Array Έ͍ͨͳ ͕ͭඞཁͳͱ͖
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠