Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - catch access to property of object [duplicate]

Is it possible to capture when a (any) property of an object is accessed, or attempting to be accessed?

Example:

I have created custom object Foo

var Foo = (function(){     var self = {};     //... set a few properties     return self; })(); 

Then there is some action against Foo - someone tries to access property bar

Foo.bar 

Is there way (prototype, perhaps) to capture this? bar may be undefined on Foo. I could suffice with capturing any attempted access to undefined properties.

For instance, if bar is undefined on Foo, and Foo.bar is attempted, something like:

Foo.prototype.undefined = function(){     var name = this.name; //name of property they attempted to access (bar)     Foo[name] = function(){         //...do something     };     return Foo[name]; } 

But functional, unlike my example.

Concept

Foo.* = function(){ } 

Background

If I have a custom function, I can listen for every time this function is called (see below). Just wondering if it's possible with property access.

Foo = function(){}; Foo.prototype.call = function(thisArg){     console.log(this, thisArg);     return this; } 
like image 576
Randy Hall Avatar asked Nov 22 '13 14:11

Randy Hall


People also ask

How can I check if the array of objects have duplicate property values?

Using the indexOf() method In this method, what we do is that we compare the index of all the items of an array with the index of the first time that number occurs. If they don't match, that implies that the element is a duplicate. All such elements are returned in a separate array using the filter() method.

How do you check if there are duplicates in JavaScript?

To check if an array contains duplicates: Use the Array. some() method to iterate over the array. Check if the index of the first occurrence of the current value is NOT equal to the index of its last occurrence. If the condition is met, then the array contains duplicates.

Does JavaScript object allow for duplicate keys?

No, JavaScript objects cannot have duplicate keys. The keys must all be unique.


1 Answers

Yes, this is possible in ES2015+, using the Proxy. It's not possible in ES5 and earlier, not even with polyfills.

It took me a while, but I finally found my previous answer to this question. See that answer for all the details on proxies and such.

Here's the proxy example from that answer:

const obj = new Proxy({}, {     get: function(target, name, receiver) {         if (!(name in target)) {             console.log("Getting non-existant property '" + name + "'");             return undefined;         }         return Reflect.get(target, name, receiver);     },     set: function(target, name, value, receiver) {         if (!(name in target)) {             console.log("Setting non-existant property '" + name + "', initial value: " + value);         }         return Reflect.set(target, name, value, receiver);     } });  console.log("[before] obj.foo = " + obj.foo); obj.foo = "bar"; console.log("[after] obj.foo = " + obj.foo); obj.foo = "baz"; console.log("[after] obj.foo = " + obj.foo); 

Live Copy:

"use strict";    const obj = new Proxy({}, {      get: function(target, name, receiver) {          if (!(name in target)) {              console.log("Getting non-existant property '" + name + "'");              return undefined;          }          return Reflect.get(target, name, receiver);      },      set: function(target, name, value, receiver) {          if (!(name in target)) {              console.log("Setting non-existant property '" + name + "', initial value: " + value);          }          return Reflect.set(target, name, value, receiver);      }  });    console.log("[before] obj.foo = " + obj.foo);  obj.foo = "bar";  console.log("[after] obj.foo = " + obj.foo);  obj.foo = "baz";  console.log("[after] obj.foo = " + obj.foo);

When run, that outputs:

Getting non-existant property 'foo' [before] obj.foo = undefined Setting non-existant property 'foo', initial value: bar [after] obj.foo = bar [after] obj.foo = baz
like image 119
5 revs, 3 users 98% Avatar answered Oct 02 '22 08:10

5 revs, 3 users 98%