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

楽しいProxy

Ryo Nakamura
December 20, 2018

 楽しいProxy

Proxy is so much fun! @We are JavaScripters! #27

Ryo Nakamura

December 20, 2018
Tweet

More Decks by Ryo Nakamura

Other Decks in Programming

Transcript

  1. (ϨϏϡΞʔ) { type: Array, validate(values) { return values.length !== 0;

    }, } const fakeData = { length : 1000 }; ͜ΕͰಥഁͰ͖ΔͷͰ͸ɾɾɾʁ(Request Changes)
  2. (ϨϏϡΞʔ) 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; }, }
  3. 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
  4. > 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
  5. $ cat logger.log [log]: plz log me [error]: this is

    an error! [count]: cat [count]: dog [count]: cat ࣮ߦ࣌ʹϑΝΠϧʹॻ͖ग़͢
  6. 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; }, }); };
  7. 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 Ά͍͜ͱ͕Ͱ͖Δ
  8. 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`); } }) );
  9. > 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Λ࡞ΕΔ