Created
October 18, 2019 09:28
-
-
Save pastleo/acd06a09a43a7cc392cbddd4a7f5dfbd to your computer and use it in GitHub Desktop.
experiments about js proxy api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy | |
const magicObj = new Proxy({}, { | |
get: (obj, name) => { | |
if (obj[name] === undefined) obj[name] = 1; | |
else obj[name]++; | |
return obj[name]; | |
}, | |
set: (obj, name, value) => { | |
if (obj[name] === undefined) return Reflect.set(obj, name, value); // will explain below | |
else return Reflect.set(obj, name, obj[name] + value); | |
}, | |
has: (obj, name) => { | |
console.log(obj, 'has', name, ':', obj[name] !== undefined); | |
return false; | |
}, | |
deleteProperty: (obj, name) => { | |
console.log(obj, 'sorry not allowed to delete', name); | |
return true; | |
// The deleteProperty method must return a Boolean indicating whether or not the property has been successfully deleted. | |
// return false will throw TypeError: 'deleteProperty' on proxy: trap returned falsish for property 'xxx' | |
// usually return Reflect.deleteProperty(obj, name) | |
}, | |
ownKeys: (obj) => { | |
console.log(obj, 'ownKeys'); | |
return []; | |
}, | |
}); | |
console.log('global.magicObj = magicObj'); | |
global.magicObj = magicObj; | |
console.group('test Proxy handler.get'); | |
console.log(magicObj.asdf); | |
console.log(magicObj.asdf); | |
console.log(magicObj.asdf); | |
console.groupEnd(); | |
console.group('test Proxy handler.set'); | |
magicObj.asdf = 100; | |
console.log(magicObj.asdf); | |
console.groupEnd(); | |
console.group('test Reflect'); | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect | |
// basically Reflect is used to mutate objects and returns true/false to indicate if the operation is successful | |
const objForRelect = {}; | |
console.log(Reflect.set(objForRelect, 'test', 123)); | |
console.log(objForRelect); | |
console.groupEnd(); | |
console.group('test Proxy handler.has'); | |
console.log('asdf' in magicObj); | |
console.log('qwer' in magicObj); | |
console.groupEnd(); | |
console.group('test Proxy handler.deleteProperty'); | |
delete magicObj['asdf']; | |
delete magicObj.asdf; | |
console.groupEnd(); | |
console.group('test Proxy handler.ownKeys'); | |
for (let a in magicObj) console.log(a); | |
console.groupEnd(); | |
function SomeFuncClass(constructing, ...args) { | |
console.log('SomeFuncClass called', { args }); | |
if (constructing) return; | |
else return { some: 'value' }; | |
// when called with new keyword, | |
// returning non-object value will make newed value be 'this' (so this function is a constructor), | |
// otherwise newed value will be return value | |
} | |
// better class style as below, but I want to make the 'class' function for fun | |
// class SomeClass { | |
// constructor(...args) { | |
// console.log('SomeClass.constructor', { args }); | |
// } | |
// } | |
SomeFuncClass.prototype.haha = function(...args) { // use arrow function will not get 'this' | |
console.log('haha', { args, t: this }); | |
}; | |
const EnhancedFuncClass = new Proxy(SomeFuncClass, { | |
apply: (target, thisArg, args) => { | |
console.log('handler.apply', { target, thisArg, args }); | |
return target; | |
}, | |
construct: (target, args) => { | |
console.log('handler.constructor', { target, args }); | |
// return new target('hello?'); | |
return { hello: 'world' }; | |
} | |
}); | |
console.group('test Proxy handler.apply'); | |
console.log(SomeFuncClass.apply('this?', [false, 'asdf'])); | |
console.log(SomeFuncClass.call('this?', false, 'asdf', 'qwer')); | |
console.log(SomeFuncClass(false, 'asdf', 'qwer')); | |
console.log(EnhancedFuncClass.apply('this?', [false, 'asdf'])); | |
console.log(EnhancedFuncClass.call('this?', false, 'asdf', 'qwer')); | |
console.log(EnhancedFuncClass(false, 'asdf')('qwer')); | |
console.groupEnd(); | |
console.group('test Proxy handler.construct'); | |
console.log(new SomeFuncClass(true, 'qwer')); | |
console.log(new EnhancedFuncClass(true, 'zxcv')); | |
const test1 = new SomeFuncClass(true, 'qwer'); | |
console.log(test1.haha('hello?')); | |
const test2 = new EnhancedFuncClass(true, 'zxcv'); | |
console.log(test2.hello); | |
console.groupEnd(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment