Skip to content

Instantly share code, notes, and snippets.

@pastleo
Created October 18, 2019 09:28
Show Gist options
  • Save pastleo/acd06a09a43a7cc392cbddd4a7f5dfbd to your computer and use it in GitHub Desktop.
Save pastleo/acd06a09a43a7cc392cbddd4a7f5dfbd to your computer and use it in GitHub Desktop.
experiments about js proxy api
// 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