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

楽しいProxy

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Ryo Nakamura Ryo Nakamura
December 20, 2018

 楽しいProxy

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

Avatar for Ryo Nakamura

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Λ࡞ΕΔ