- Note: Proxy works in browser and nodejs.
- Source: MDN Proxy
- Todo: Do continue learning from examples from above link, and master every example's logic though.
- Todo: Another decent article(already covered in this repo though): https://www.javascripttutorial.net/es6/javascript-proxy/
Google Docs - Learn markdown-autodocs
- Note: I have disabled this file's formatting with prettier in
.prettierignore
file because prettier adds empty lines before and after the code snippets which are then removed byautodocs-github-actions
when its run on server. Thus I'm removing prettier for this file. (Future: If I ever want to use prettier --- then the way is to run autodocs on your own in the workflow file and then re-run the prettier before commiting the code so any empty line side-effects made by autodocs are removed even before they are commited to the git.
const assert = require('assert');
const handler = {
get(target, property, receiver) {
if (property in target) {
return target[property]; // return the property value
} else {
return (...args) => {
if (property === 'increment') {
target[args[0]] += args[1];
}
return target[args[0]];
};
}
},
};
const myTarget = { alice: 1, bob: 1 };
const myProxy = new Proxy(myTarget, handler);
assert.strictEqual(typeof myProxy, 'object', 'Type of myProxy should be `object`');
assert.strictEqual(myProxy.alice, 1, 'myProxy.alice should be 1');
assert.strictEqual(myProxy.bob, 1, 'myProxy.bob should be 1');
assert.strictEqual(typeof myProxy.anyOtherProperty, 'function', 'Type of `myProxy.anyOtherProperty` should be a function');
assert.strictEqual(myProxy.increment('alice', 2), 3, 'Return value from `myTarget.alice(..)` should be equal to 3.');
assert.strictEqual(myProxy.alice, 3);
assert.strictEqual(myTarget.alice, 3);
assert.strictEqual(myProxy.increment('bob', 3), 4, 'Return value from `myTarget.bob(..)` should be equal to 4.');
assert.strictEqual(myProxy.bob, 4);
assert.strictEqual(myTarget.bob, 4);
const updateBob = myProxy.increment('bob', 3);
console.log("updateBob:", updateBob);
// new text
const handler = {
get(target, property, receiver) {
return (...args) => {
target.count += args[0];
console.log('property?:', property); // increment
return target.count;
};
},
};
const myTarget = { count: 1 };
const rpc = new Proxy(myTarget, handler);
const count = rpc.increment(2);
console.log("count:", count); // 3
console.log("rpc:", rpc); // { count: 3 }
// Usage in my-rpc frontend: [Click here](https://github.com/sahilrajput03/learn-rpc-middlewares/blob/main/my-rpc/index.html)
const handler = {
get(target, property, receiver) {
return (...args) => {
console.log('property?:', property);
console.log('args?', args, '\n');
};
},
};
const myTarget = {};
const rpc = new Proxy(myTarget, handler);
rpc.a('1');
// property?: a
// args? ['1']
rpc.b('one', 'two');
// property?: b
// args? ['one', 'two']
// no handler example
const handler = {};
const myTarget = {
message1: 'hello',
message2: 'everyone',
};
const myProxy = new Proxy(myTarget, handler);
console.log(myProxy.message1); // hello
console.log(myProxy.message2); // everyone
// * Popular traps(properties) of handler object are:
// - get
// - set and
// - apply
const handler = {
get: function (target) {
// here we get reference to object itself.
console.log(target);
return 'world';
},
};
const myTarget = {
message1: 'hello',
message2: 'everyone',
};
const myProxy = new Proxy(myTarget, handler);
console.log(myProxy.message1); // world
console.log(myProxy.message2); // world
// * What is Reflect.get ?, src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get
// * The static Reflect.get() method works like getting a property's value from an object
const object1 = {
x: 1,
y: 2,
}
console.log(Reflect.get(object1, 'x'))
// expected output: 1
const array1 = ['zero', 'one']
console.log(Reflect.get(array1, 1))
// expected output: "one"
const handler = {
get: function (target, property) {
// Although there is third param i.e., receiver but there's no good usage of it known yet according to my research.
// Learn about receiver(i.e., 3rd param) @ here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get
// console.log(object) // { message1: 'hello', message2: 'everyone' }
// console.log(property) // message1, message2
if (property === 'message2') {
return 'world';
}
// return Reflect.get(...arguments)// This was from mdn, but it is insancely used here IMO ~sahil.
return target[property];
},
};
const myTarget = {
message1: 'hello',
message2: 'everyone',
};
const myProxy = new Proxy(myTarget, handler);
console.log(myProxy.message1); // hello
console.log(myProxy.message2); // world
// In this simple example, the number 100 gets returned as the default value when the property name is not in the object. It is using the get() handler.
const handler = {
get: function (obj, keyName) {
return keyName in obj ? obj[keyName] : 100;
},
};
let myTarget = {};
const myProxy = new Proxy(myTarget, handler);
myProxy.a = 1;
myProxy.b = undefined;
console.log(myProxy.a, myProxy.b, 'c' in myProxy, myProxy.c);
// 1, undefined, false, 100
// In below example we are mimicing default js object behaviour with below proxy example.
let handler = {
get: (obj, keyName) => {
return obj[keyName];
},
set: (obj, keyName, inputValue) => {
obj[keyName] = inputValue;
},
};
let myTarget = {
a: 10,
b: 20,
};
const myProxy = new Proxy(myTarget, handler);
myProxy.c = 30;
console.log(myProxy.c); // 30
const handler = {
get: (obj, keyName) => {
console.log('::get', { keyName });
return obj[keyName]; // Array's `push` method is returned when `myProxy.push()` is executed
},
set: (obj, keyName, inputValue) => {
console.log('::set', { keyName, inputValue });
obj[keyName] = inputValue; // Array's length is set push method on the array on `line 11`(i.e., method returned from the get method of the proxy handler, yikes!).
return true;
},
};
const myTarget = [];
const myProxy = new Proxy(myTarget, handler);
myProxy.push(1);
// Output:
// ::get { keyName: 'push' } // push method is retrieved
// ::get { keyName: 'length' } // length is retrieved
// ::set { keyName: '0', inputValue: 1 } // On property '0' set value `1`
// ::set { keyName: 'length', inputValue: 1 } // On property 'length' set value `1`
console.log('---');
myProxy[0] = 2;
// Output:
// ::set { keyName: '0', inputValue: 2 }
Thankyou.