I'm having a bit of trouble with a small Javascript library that I am creating for practice that mimics jQuery and other libraries. As of now it does not work. I'm very new to Javascript and to scripting in general as I have only started teaching myself, so chances are I'm simply missing something that would be obvious to most. I have tried searching for a solution, but I have not been able to find one, so I have resorted to asking about it myself.
This is the library itself:
(function(window, undefined) {
var document = window.document
var $m = function(obj) {
if (typeof obj === "object") {
return obj
}
else {
return document.getElementById(obj)
}
class: function(name){
var ele = document.getElementsByTagName('*')
var objects = []
for (var q = 0 ; q < ele.length ; ++q){
if (ele[q].className === name){
objects.push(ele[q])
}
}
return objects
}
s: function(){
return this.style
}
window.$m = $m
})(window)
A brief edit: $m is intended to be an object with methods class and s.
And this is how it is referenced in a simple test page:
<h1 class="heading" onmouseover="$m(this).s.setAttribute('text-decoration', 'underline')" onmouseout="$m(this).s.setAttribute('text-decoration', 'none')">Testing.</h1>
Another edit: I have attempted to do this, and although it throws no errors it does not work correctly. I'm a bit stumped with what exactly is not being called.
Here is the new library:
(function(window, undefined) {
//set document to this local scope
var document = window.document
//create $m object
var $m = function(obj) {
//if it is anything but an element return itself
if (typeof obj === "object") {
return new init(obj);
}
//if it is an element return that element
else {
return new init(document.getElementById(obj));
}
}
function init(elem){
//set properties
this.elem = elem;
}
init.prototype = {
//return style
sty: function() {
return this.elem.style;
},
//return all objects with a certain class
cla: function() {
var allelem = document.getElementsByTagName('*')
var give = []
//gather all elements in the document and get those with matching class
for (var q = 0 ; q < allelem.length ; ++q){
if (allelem[q].className === this.elem.className){
give.push(allelem[q]);
}
}
//return found elements
return give;
}
}
//expose $m to global scope
window.$m = $m;
})(window)
and an attempt to fix how it is referenced:
<h1 class="heading" id="test" onmouseover="$m(this).sty.textDecoration='underline'" onmouseout="$m(this).sty.textDecoration='none'">Testing.</h1>
There's a couple of things wrong here.
First, as user1689607 says, your syntax is invalid; you want (I think) the following for the last part:
function class(name){
var ele = document.getElementsByTagName('*')
var objects = []
for (var q = 0 ; q < ele.length ; ++q){
if (ele[q].className === name){
objects.push(ele[q])
}
}
return objects
}
function s() {
return this.style
}
This still won't work, though, since class is a reserved word.
Furthermore, your code from further up isn't going to allow you to do what you're trying to do in your HTML. What you're looking for is to create a new object containing the parameter you pass to $ as a field, with the functions you've defined as members.
Try the following:
function MyObjConstructor(param) {
this.field = param;
}
MyObjConstructor.prototype =
{
s:function(){...}//As your S function, but replace "this" with "this.field"
clazz:function(){...}//As your class function, but replace "this" with "this.field"
}
and finally
function $m(obj) {
if (typeof obj === "object") {
return new MyObjConstructor(obj);
}
else {
return new MyObjConstructor(document.getElementById(obj));
}
}
This results in each object that is passed to your $ function being wrapped, and exposing the appropriate methods. I'm not sure how jQuery does it, but this is probably a good place to start.
class: function(name){ … }
s: function(){ … }
I don't know what you expect those statements to do. Usually, something like this appears in an object literal, but in here you just have labeled statements. Also, you are missing a closing brace somewhere.
From your usage, it seems you want them to be properties of the returned object. As you return a plain DOM element, you would need to extend them with those custom properties:
var el = document.getElementById(obj);
el["class"] = function(name){ … }; // notice that "class" is a reserved word,
// you should not use it as a (property) identifier
el.s = function(name){ … }; // notice this defines a /function/,
// which you still had to invoke - you can't just use ".s…"
return el;
This is generally considered bad practice, and you won't rejoice in it. Read the article for better patterns.
Btw, style declarations have no setAttribute method as DOM elements have. You can either directly assign to a property, or use the setProperty method.
Also, the s or sty property is a function. You will need to call it before you can access the style declaration object: $m(this).sty().textDecoration = …; "getStyle" might be a more appropriate name.
Related
I was trying to make my code more readable and ran into an oddity with my build and events objects that I attached to the prototype. Is there a way to do this?
function Something(){
this.$container = $('<div>');
return this;
}
Something.prototype.build = {
list: function(){
this.$container.append(...);
}
}
Currently what happens is when build.list calls this, this refers to the build object, not the Something object.
I can't quite figure out another way of using it this way without renaming everything to buildList, buildComponentArray, and etc. Semantics maybe.
This is a possible solution
function Something(){
this.$container = "<div></div>";
//this creates a new object in the prototype chain for every instance
this.build = Object.create(this.build);
for (var prop in this.build) {
if (this.build.hasOwnProperty(prop) && typeof this.build[prop] === "function") {
this.build[prop] = this.build[prop].bind(this);
}
}
return this;
}
Something.prototype.build = {
list: function(){
console.log(this.$container);
}
}
Basically you'll bind every function in your this.build object to a function bound to this. You could extract this in a utility function and then bind all nested object you need to this. I suppose it must be possible too by manipulating/build the prototype chain but I haven't found it.
I know most of you recommend refactoring, but I thought to put this out there just so you have a complete set of solutions.
Edit
As pointed out, you need to move the build interface to your constructor in order to have this bound correctly. This solution is just a way to do this without having to move your code.
solution without using Object.create
This one is cleaner and more explicitly states what it does without messing with prototypes.
function Something(){
this.$container = "<div></div>";
var build = this.build;
this.build = {};
for (var prop in build) {
if (build.hasOwnProperty(prop) && typeof build[prop] === "function") {
this.build[prop] = build[prop].bind(this);
}
}
return this;
}
Something.prototype.build = {
list: function(){
console.log(this.$container);
}
}
I would like to implement the following behavior in JS. Please note that the syntax is symbolic.
This is my parent class
class = TList {
FList: array;
function AddElement(Ele) {
Flist.Add(Ele)
};
function RemoveEle(Ele) {
FList.Remove(Ele)
};
}
Now I'm going to inherit from this class. My child class should automatically have all the properties of the parent and should be able to extend them without rewriting the code.
class = TAlertList(inherit from TList) {
function AddElement(Ele) {
Alert('element will be added');
call.parent.AddElement(Ele)
};
function RemoveElement(Ele) {
call.parent.RemoveElement(Ele);
Alert('element removed');
}
}
Please note how I inherit the parent methods at places I wish.
Now I should be able to create an object from my child class and do the following.
MyAlertList = new TAlertList;
MyAlertList.Add('hello');
console.log(MyAlertList.FList);
I should be able to inherit more child classes from TAlertList and be able to change the existing behavior. I need to do this in pure ES5 without using any libraries. Standard OOP practices are expected.
Please note that the TList constructor should be applied to the TAlertList instance;
ES5, first set up the base constructor
function TList() {
this.Flist = [];
// ...
}
TList.prototype = {
constructor: TList,
AddElement: function AddElement(Ele) {
this.Flist.push(Ele);
},
RemoveEle: function RemoveEle(Ele) {
var i = this.Flist.lastIndexOf(Ele);
if (i !== -1)
this.Flist.splice(i, 1);
}
};
Next set up the constructor which extends it, see how this means calling the base constructor on the instance being created by the extended constructor and creating a prototype object which inherits the prototype of the base constructor
function TAlertList() {
// construct from base
TList.call(this);
// further construct
// ...
}
TAlertList.prototype = Object.create(TList.prototype);
TAlertList.prototype.constructor = TAlertList;
// depending on how you want to reference stuff
TAlertList.prototype.AddElement = function AddElement(Ele) {
alert('element will be added');
TList.prototype.AddElement.call(this, Ele);
};
TAlertList.prototype.RemoveElement = function RemoveElement(Ele) {
TList.prototype.RemoveEle.call(this, Ele);
alert('element removed');
};
ES6 syntax makes use of the super keyword
class TList {
constructor() {
this.FList = [];
}
AddElement(Ele) {
this.Flist.push(Ele);
}
RemoveEle(Ele) {
var i = this.Flist.lastIndexOf(Ele);
if (i !== -1)
this.Flist.splice(i, 1);
}
}
class TAlertList extends TList {
constructor() {
super();
}
AddElement(Ele) {
alert('element will be added');
super.AddElement(Ele);
}
RemoveElement(Ele) {
super.RemoveEle(Ele);
alert('element removed');
}
}
Back to ES5, generalising as a factory so you can see a sort of algorithm of how to do it
function extend(baseConstructor, extendedConstructor, prototypeLayer) {
function Constructor() {
var i = 0, j = 0, args = Array.prototype.slice.call(arguments);
i = j, j += baseConstructor.length;
baseConstructor.apply(this, args.slice(i, j));
i = j, j = args.length;
extendedConstructor.apply(this, args.slice(i, j));
}
Object.defineProperty(Constructor, 'length', { // fix .length
value: baseConstructor.length + extendedConstructor.length,
configurable: true
});
Constructor.prototype = Object.create(baseConstructor.prototype);
Constructor.prototype.constructor = Constructor;
Object.assign(Constructor.prototype, prototypeLayer);
return Constructor;
}
So then
function Foo(x) {this.foo = x;}
Foo.prototype.fizz = 1;
var Bar = extend(Foo, function (x) {this.bar = x;}, {buzz: 1});
// ...
var b = new Bar('foo', 'bar');
b.foo; // "foo"
b.bar; // "bar"
b instanceof Foo; // true
b instanceof Bar; // true
b.fizz; // 1
b.buzz; // 1
Please note that this is an example of the algorithm you should be following when you write each extended constructor, not production code
Your code would be the following
function TList(){
this.FList = [];
}
TList.prototype.AddElement = function(Ele){
this.FList.push(Ele);
}
TList.prototype.RemoveElement = function(Ele){
this.FList.splice(Ele,1); //Ele is the index to remove;
}
This is an approximation to know how the inherit works in JavaScript.
function TAlertList (){
TList.call(this);
}
TAlertList.prototype = Object.create(TList.prototype);
TAlertList.prototype.constructor = TAlertList;
TAlertList.prototype.AddElement = function(ele){
alert('Element will be added');
TList.prototype.AddElement.call(this,ele);
};
TAlertList.prototype.RemoveElement = function(ele){
alert('Element will be remove');
TList.prototype.RemoveElement.call(this,ele);
};
So, the classic super call is
ParentClass.prototype.myMethod.call(this,args);
This is Q&A
Edit - Don't forget to read #paul's comment too if you planning to read the full text.
Almost all the answers came in were based on the popular "Person" example in the MDN documentation about JS OOP.
The theory behind this method is to put the fields of the object inside a constructor function while implementing the methods in a prototype object. A child object can inherit all the fields by calling the constructor function with a contrived this value. Also it can inherit all the methods by having the same prototype object of the parent as it's prototype object too. The only rule is that you need to call the methods using call or apply to point the methods to the correct this object when implementing inheritance.
I didn't like this approach for two reasons.
The fields and methods of an objects has to be separated between two objects (fields - constructor function, methods - prototype). This doesn't have the flavor of a unique behavior of a unique entity - which should be a single class.
You have to specify the name of the parent object when inheriting. This is not automatic. Let's say object C inherits from the object A. So, inside the methods of the object C, you need to mention object A when inheriting from it. (TList.prototype.AddElement.call(this, Ele);) What if object B comes in between later on? You will have to change all the inheriting methods of C to call from B. This is in no way near good inheritance.
I wanted to overcome these problems in MDN method. I came up with the following model with no this no call and no apply. Code is simple and easy to follow. You don't have to mention the name of the parent object when inheriting from it. So, a new class can come in between the parent and the child at any time without too many changes. Please discuss this and point out the weaknesses of this model.
Here is the function which returns the parent object.
function tList() {
var ret = Object.create(null);
ret.list = [];
ret.addElement = fucntion(ele) {
ret.list.push(ele)
};
return ret;
}
//You can create tList object like this:
var myList = tList();
myList.addElement('foo');
Now comes the child object:
function tAlertList() {
var ret = Object.create(tList());
//Lets inherit with the fashion of overriding a virtual method
ret.addElement = function(ele) {
//Here is new code
alert('Adding element ' + ele);
//Automatic inheritance now
Object.getPrototypeOf(ret).addElement(ele);
}
return ret;
}
//Just create the child object and use it
var myAlertList = tAlertList();
myAlertList.addElement('buzz') ;
You can have grand children object and inherit from parent without mentioning their names. Let's say you have to put tCustomList between tList and tAlertList. All you have to do is to tell the tAlertList to inherit from tCustomList in a single place. (var ret = Object.create(tCustomList());) Everything else remain the same.
Here is the fiddle.
With pure ES5, you could do it like this:
function TList() {
this.FList = []; //not really ideal.
}
TList.prototype.addElement = function(ele) {
this.FList.push(ele);
};
TList.prototype.removeElement = function(ele) {
this.FList.splice(this.FList.indexOf(ele), 1);
}
function TAlertList(){
this.FList = [];
}
TAlertList.prototype = new TList(); //inherit from TList
TAlertList.prototype.constructor = TAlertList; //reset constructor
TAlertList.prototype.addElement = function(ele) {
alert('element will be added');
TList.prototype.addElement.call(this, ele);
};
TAlertList.prototype.removeElement = function(ele) {
alert('element removed');
TList.prototype.removeElement.call(this, ele);
};
Couple of notes:
The FList property of its parent will actually be shared amongst all objects that inherit from the parent unless overwritten. That means that if you don't overwrite FList you'll get this:
var a = new TAlertList();
var b = new TAlertList();
a.push(1); //b.Flist === [1]
In my opinion, it would be best if you named your children functions with other names different from the parent. This way you don't need to do:
TList.prototype.function.call(this, parameter1, parameter2, ..);
You can just call them like this:
this.function(paremeter1, parameter2);
Of course, it's not a static way to call the parent as you can overwrite the function with your own. Then again TList.prototype.function isn't necessary the function of the parent of the object that owns the function. For that you'd need to use non-standard ES5 __proto__ property.
this.__proto__.function.call(this, parameter1, parameter2, ..);
Unless you plan on juggling the function around different objects, you don't need that.
I create a class with a function like this
var Obj=function(){this.children=[];this.parent=null;}//a base class
Obj.prototype.index=function(child){
// the index of current obj
if(arguments.length==0){
return this.parent?this.parent.index(this):0;
}
// the index of a child matchs specific obj [to be override]
return -1;
}
basically it is just an overload function composed of index() and index(child).
Then I create a sub class,SubObj or whatever, inherits from Obj
SubObj.prototype.prototype=Obj;
Now, it's time to override the index(child) function,however, index() is also in the function an I don't want to overwrite it too.
One solution is to write like this
var Obj=function(){this.children=[];this.parent=null;}//a base class
Obj.prototype.index=function(child){
// the index of current obj
if(arguments.length==0){
return this.parent?this.parent.index(this):0;
}
// the index of a child matchs specific obj [to be override]
return this._index(this);
}
Obj.prototype._index=function(this){
return -1;
}
SubObj.prototype._index=function(this){/* overwriteing */}
But this will easily mislead other coders as _index(child) should be both private(should not be used except index() function) and public(is an overload function of index(),which is public)
you guys have better idea?
From my understanding, what you are trying to do should be quite doable. Although, I'd take RobG's advice and move away from trying to force a classical design onto JavaScript; JavaScript is about objects, not classes. Anyways, I digress. Here's a solution you can try out:
var Obj = function () {
this.children = [];
this.parent = null;
};
Obj.prototype.index = function (child) {
if (arguments.length === 0) {
return this.parent ? this.parent.index(this) : 0;
}
return -1;
};
var SubObj = function() {};
SubObj.prototype = new Obj();
SubObj.prototype.index = (function (base) {
var someIndex = 10;
return function (child) {
// If child is defined then we
// do our own processing.
if (child && arguments.length === 1) {
return someIndex;
}
// Otherwise we call our base/overriden version.
return base.call(this);
};
}(SubObj.prototype.index));
// Usage:
var o = new Obj(), so = new SubObj();
o.index(); // Returns 0
so.index(); // Returns 0
so.index(o); // Returns 10
There were a few issues with your prototype chain construction (SubObj.prototype.prototype = Obj doesn't actually do anything) and the definition of the index() method on the SubObj.prototype object (namely the use of this as an argument -- this will likely cause a world of pain when you try to run this in virtually any browser). I've made the fixes and implemented the override you seek (at least I think it's what you're after). Let me know if I misunderstood anything.
we currently learn some Javascript stuff in a course at the university.
For that we implement a library for common tasks like show(), hide(), write and such things.
Currently im running with an implementation like:
var myLib_maker = function () {
/*
private scope
*/
var debuggingMode=true;
var currentElement=null;
/*
end private scope
*/
return {
getElement: function (id) {
var o;
if (typeof id === 'string') { o = document.getElementById(id); }
if (!!(o && o.nodeType !== 1)) {
throw {
name: 'Type Error',
message: 'Wrong node type at id: '+id
}
}
currentElement=o;
return this;
},
getCurrentElement: function() {
console.log(currentElement)
return currentElement;
},
isVisible: function () {
return this.getCurrentElement().style.display.toLowerCase() === "block";
},
show: function () {
this.debug("show "+this.getCurrentElement())
this.getCurrentElement().style.display = "block";
return this;
},
hide: function () {
this.debug("hide "+this.getCurrentElement())
this.getCurrentElement().style.display = "none";
return this;
},
toggle: function() {
this.debug("toggle "+this.getCurrentElement())
this.isVisible() ? this.hide(): this.show();
return this;
},
write: function (content){
this.debug("write to"+this.getCurrentElement().id);
var tg = this.getCurrentElement().tagName.toLowerCase();
if (tg === 'input' || tg === 'textarea') {
currentElement.value = content;
} else {
currentElement.innerHTML = content;
}
return this
},
debug: function (what) {
if (debuggingMode===true){
console.log("[DEBUG] "+what);
}
return this;
}
};
}
var myLib=myLib_maker();
Than I have an external function (for testing) to switch 2 textareas contents.
function switchEditors(id1, id2){
c1=myLib.getElement(id1).getCurrentElement().value;
c2=myLib.getElement(id2).getCurrentElement().value;
myLib.getElement(id1).write(c2)
myLib.getElement(id2).write(c1)
}
I first tried with the following code, which obviously does not work, cause I overwrite my private currentElement and so I write always to id2
function switchEditors(id1, id2){
tmp=myLib.getElement(id1).getCurrentElement().value
myLib.getElement(id1).write(myLib.getElement(id2).getCurrentElement().value)
myLib.getElement(id2).write(tmp)
}
But what I really wanted initially was not using a private currentElement variable.
The first implementation of the write method extended the Element Object
Element.prototype.write= function (content){
var tg = this.tagName.toLowerCase();
if (tg === 'input' || tg === 'textarea') {
this.value = content;
} else {
this.innerHTML = content;
}
return this;
}
and such the getElement function returned
document.getElementById(id)
I want cascading (I hope this is the right word -> I mean the myLib.getElement("myid").show().hide() concatenation thing) and getting direct access to
all Element attributes but we must not use global scope for our library, so I have to encapsulate my library in any way.
So is there an elegant way to use the cascading thing and be able to get a direct access to all attributes on an element object without implementing each method within the global element scope?
Or is my lib desing completely wrong and has to be done totally different.
If so, just tell me, I appreciate any help.
(I tried to figure out how jQuery actually implement these things, but didn't get a real clue how it is done ... too much code ... :) )
I hope I described my wishes and requirements. If not please ask for more specific details.
As you've figured out, the currentElement is shared between calls to getElement. Instead you could create a new instance of myLib-object with Object.create and bind currentElement to that.
getElement: function (id) {
var o, self = Object.create(this);
/* ... */
self.currentElement = o;
return self;
}
And use this.currentElement throughout so that each call uses its own current element.
While Magnar's solution will work with this (singleton) pattern, it is a better idea to avoid creating a whole new object each time you call getElement. There is a reason for creating "classes" instead of singletons.
You can do it like this:
var MyLib_Maker = (function () { // I capitalized the class as a helpful
// convention recommended by Douglas Crockford
// Private static vars
var debuggingMode = true;
var currentElement = null;
// Private static methods
function _myMethod (x, y) { // call below by _myMethod(3,4);
return x * y;
}
// Private instance methods (but only if called properly:
// invoke below by _instMethod.call(this, 3, 4); )
function _instMethod (x, y) {
return this.anInstanceNumber * x * y;
}
// Private instance properties (quite cumbersome but doable if you
// absolutely must--e.g., for classes whose objects need to be clean when iterated)
// See http://brettz9.blogspot.com/2009/02/true-private-instance-variables-in.html
// and http://brettz9.blogspot.com/2009/02/further-relator-enhancements.html
// (put the Relator inside the closure if you don't want it reusable (and public),
// but then your extending classes must be inside the closure too)
function MyLib_Maker (arg1, arg2) {
// I recommend the following check to allow your class to be
// instantiated without the 'new' keyword (as in jQuery/$):
if (!(this instanceof MyLib_Maker)) {
return new MyLib_Maker(arg1, arg2);
}
// Other constructor code here
// ...
}
// Methods added on the prototype benefit from merely
// providing a low-memory reference across all instances;
// this will avoid adding a whole new object unnecessarily
// into memory
MyLib_Maker.prototype.getElement = function () {
// ....
return this; // Keep the chain going (if not public
// properties, you could add a method which also avoids
// extending the chain, like $(el).get() in jQuery
};
return MyLib_Maker;
}()); // We can invoke immediately to wrap up the closure
// Usage example:
var mlm = MyLib_Maker(2, 3).getElement().doSomething();
By the way, what you describe is called chaining; cascading is used in the likes of CSS to indicate that like different waves out of a waterfall, one may write over the other, as you can do by writing rules which override prior ones in CSS.
And it is good you moved away from overriding the Element object because, whatever the browser incompatibilities, this is the worst kind of global namespace pollution because it affects all elements, increasing the chance that another library which depends on that method (or which is careless in overriding the built-in prototypes itself) may get you unexpected results.
Do JavaScript objects/variables have some sort of unique identifier? Like Ruby has object_id. I don't mean the DOM id attribute, but rather some sort of memory address of some kind.
If you want to lookup/associate an object with a unique identifier without modifying the underlying object, you can use a WeakMap:
// Note that object must be an object or array,
// NOT a primitive value like string, number, etc.
var objIdMap=new WeakMap, objectCount = 0;
function objectId(object){
if (!objIdMap.has(object)) objIdMap.set(object,++objectCount);
return objIdMap.get(object);
}
var o1={}, o2={}, o3={a:1}, o4={a:1};
console.log( objectId(o1) ) // 1
console.log( objectId(o2) ) // 2
console.log( objectId(o1) ) // 1
console.log( objectId(o3) ) // 3
console.log( objectId(o4) ) // 4
console.log( objectId(o3) ) // 3
Using a WeakMap instead of Map ensures that the objects can still be garbage-collected.
No, objects don't have a built in identifier, though you can add one by modifying the object prototype. Here's an example of how you might do that:
(function() {
var id = 0;
function generateId() { return id++; };
Object.prototype.id = function() {
var newId = generateId();
this.id = function() { return newId; };
return newId;
};
})();
That said, in general modifying the object prototype is considered very bad practice. I would instead recommend that you manually assign an id to objects as needed or use a touch function as others have suggested.
Actually, you don't need to modify the object prototype. The following should work to 'obtain' unique ids for any object, efficiently enough.
var __next_objid=1;
function objectId(obj) {
if (obj==null) return null;
if (obj.__obj_id==null) obj.__obj_id=__next_objid++;
return obj.__obj_id;
}
I've just come across this, and thought I'd add my thoughts. As others have suggested, I'd recommend manually adding IDs, but if you really want something close to what you've described, you could use this:
var objectId = (function () {
var allObjects = [];
var f = function(obj) {
if (allObjects.indexOf(obj) === -1) {
allObjects.push(obj);
}
return allObjects.indexOf(obj);
}
f.clear = function() {
allObjects = [];
};
return f;
})();
You can get any object's ID by calling objectId(obj). Then if you want the id to be a property of the object, you can either extend the prototype:
Object.prototype.id = function () {
return objectId(this);
}
or you can manually add an ID to each object by adding a similar function as a method.
The major caveat is that this will prevent the garbage collector from destroying objects when they drop out of scope... they will never drop out of the scope of the allObjects array, so you might find memory leaks are an issue. If your set on using this method, you should do so for debugging purpose only. When needed, you can do objectId.clear() to clear the allObjects and let the GC do its job (but from that point the object ids will all be reset).
const log = console.log;
function* generateId() {
for(let i = 0; ; ++i) {
yield i;
}
}
const idGenerator = generateId();
const ObjectWithId = new Proxy(Object, {
construct(target, args) {
const instance = Reflect.construct(target, args);
instance['id'] = idGenerator.next().value;
return instance;
}
})
const myObject = new ObjectWithId({
name: '##NativeObject'
});
log(myObject.id);