Add a JavaScript getter/setter to a native unconfigurable property - javascript

I am using special getter/setters to intercept changes made to properties of an object, and it currently works great for any normal user-defined properties. However, I would love if I could employ the same idea to built-in properties like HTMLInputElement.value or Array.length, but these are unfortunately defined as unconfigurable and thus I get an error when attempting to redefine them using a getter/setter.
I'm just wondering if there's any kind of (reliable) hack that I can do to force these to be redefined without breaking their internal operation.
If not, I'll probably be forced to define alternate properties for all of these that simply map to the native properties and use them instead, but that's just so not ideal.

Work with JavaScript 1.8.1 on later : Defining getters and setters

that is not in any way a good practise, but if you really need to, those functions are defined on the prototype level so:
Array.prototype.length = (function(){})();
Ok, i think even this approach doesn't work with some functions, they must be protected

Related

Function that acts like a decorator, but uses mutation instead of wrapping?

A decorator adds additional functionality to an object by "wrapping" around the original value.
Is there a name for an object or function that ingests a pre-constructed object and adds additional functionality to it via mutation?.
Example:
function mutatesObjects(target) {
target.additionalFunctionality = "I've been mutated!";
}
This is similar to a contrcutor or factory except that it is adding functionality to an object that was already created.
Is there a name for this pattern?
Depending on the purpose for this change, Monkey Patching might apply.
"A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program)."
I would suggest Plugin name as a reference to jquery plugins.
But I also think this is actually an anti-pattern in most cases. This not only breaks the encapsulation (one of the main concepts in OOP), it goes even beyond it and changes object functionality.
Imagine a simple case where you do something like:
doSomething(object)
In the best case you can hope the object state was not changed. In the worse case you can suspect that it was mutated and it's state changed.
It's really unexpected if you get something completely different with new methods or properties.
But of course, there can be good usages (like jquery plugins).

overloading vs overriding in javascript

In a recent JavaScript interview I was asked about overloading vs overriding. I know this is a concept in Java. But is there something similar in JavaScript, and if so what would be code examples? My understanding is that overloading isn't common in javascript. Why would you need to use "overloading" in JS?
OverRiding is a bit clearer to me - an example of over riding would be in subclassing where you are inheriting from a super class but over riding some methods/properties to create unique ones for a sub class.
JavaScript does not support overloading.
JavaScript supports overriding, so if you define two functions with the same name, the last one defined will override the previously defined version and every time a call will be made to the function, the last defined one will get executed.
more read here http://blog.mastykarz.nl/overloading-functions-javascript/
There's a nice example of 'faking' JavaScript function overloading here: https://stackoverflow.com/a/457589/2754135
You basically use a parameter in your function that takes an object, that object contains any number of parameters you want.
It's not actually overloading obviously, cause that's not possible in JavaScript.
there is no need for the traditional concept of overload in javascript, because of its dynamic nature. In the more traditional programming languages, as Java, you can define a method multiple times with different signatures and the language will correctly use the method you want to call just using the signature: thats called overload of methods. On the other hand override is the possibility to redefine a method of the parent class in the child class.
To do overload in javascript it is common practice to use last parameter that is called options. For example
function yourFunction(firstParam, secondParam, options) {};
the options is just a javascript object that have props you want to pass. Then you can use the so called "options" pattern to check for props.
To do override it is more difficult in pure javascript because of the prototypal nature of the language: when you "extend" a base object with a new one, you can use .call() function of the constructor object passing this to decorate the newly created object with the parent props.
While JavaScript does not support overloading in a traditional sense,
More than the required arguments may be passed at any time to a JavaScript method, and accessed through the arguments variable. This is functionally similar.

What is the purpose of Object.prototype.toString()?

I see this code in underscore.js.
Here it is, with the alias applied:
toString = ObjProto.toString,
However, to use toString it is also accessible directly like this, w/ out using above code at all.
toString()
Try it out in the console it works fine. Try it out in direct code and it works fine as well. My guess is that older browsers may not have it accessible in this way.
How can I look into this further?
Caniuse does not not have information on it.
Google pulls up nothing useful in the first 10 or so hits.
Because it is on Object.prototype, it is accessible by global objects which inherit from Object ( only those that inherit, not all global objects ), such as Number.
But my point is, is that it is also accessible directly with out having to use a global object instance at all.
toString(some_var);
Here is one SO Q/A which suggests that window.toString is not supported in all browsers and why this is.
global objects which inherit from Object,
That's a wrong assumption, global objects are host objects and they can inherit from whatever they want or not inherit anything at all. The code for example doesn't work in IE10.
The particular toString method stored on Object.prototype is the only one that returns the internal class name for sure. Functions, arrays, numbers etc do not inherit the Object.prototype toString method but define their own toString method, as in Number.prototype.toString !== Object.prototype.toString.

What is the advantage of property attributes "feature" in ECMAScript-5?

I want to know more about usage of property attributes described here:
http://www.ecma-international.org/ecma-262/5.1/#sec-8.6.1
I can imagine usecases of these attributes, but they are very rare.
In addition writable, enumerable and configurable properties are set to false by default, but mostly I want to have these values true, so I have to set them. Why are they false by default?
Make object and set its attributes was very basic thing for me. Now there is property descriptor, which I could describe like artificial, unnatural, complicated or uncomfortable. Maybe I just missed something very essential.
So my questions are: What is main purpose of property attributes. How can we use them?
Can I avoid using property descriptor? For example with some good pattern that will set attributes for me? For example if I use Object.create with second param "Properties", it forces me to use property descriptor. So should I avoid to use this?
"...mostly I want to have these values true, so I have to set them."
Only if you have a need for them. If you don't, then just use the typical object literal syntax, or the assignment operator for new properties.
"Why are they false by default?"
I would imagine it's because there's already a syntax available that defaults them to true.
"Make object and set its attributes was very basic thing for me. Now there is property descriptor..."
Nothing has changed. It's just as basic as it was before. There are simply more tools at your disposal if you need them.
"...which I could describe like artificial, unnatural, complicated or uncomfortable."
The syntax is perhaps a little cumbersome, but if you don't like it, don't use it. If you need to set the property descriptors to something other than true, then I would think you'd be glad to have the new capabilities, irrespective of its syntax.
Also, there's likely property descriptor definition being added to object literal syntax in ECMAScript 6.
"So my questions are: What is main purpose of property attributes. How can we use them?"
That should be self-explanatory. They're for manually configuring the configurable, writeable, and enumerable settings of properties on an object. If you ever come across a situation where you need one of those settings, you'll use them.
"Can I avoid using property descriptor?"
Of course. Again, nothing has changed. They're there if you need them. If you don't, then ignore them.
"For example with some good pattern that will set attributes for me?"
Not sure what you mean, but if you want different defaults, just use a helper function, like:
function addWriteable(obj, prop, value) {
return Object.defineProperty(obj, prop, {
writeable: true
});
}
The default for writeable is false only if
If the value of an attribute is not explicitly specified by this specification for a named property
For properties you define by hand it will be true for example. The thing you should be aware of that there is a huge difference between ecmascript itself without any specification on top of it and the javascript/jscript dialects.
Either way, in general you should never do anything with these attribute properties, except if you're considering making a framework or anything along those lines. For example, prototype.js could use it to set Enumerable to false and I used it myself to redefine the Get to allow a bit of an exotic syntax which was easier for developers to use (similar to a different native syntax), but whilst doing normal stuff you don't need it.

Why is it Object.defineProperty() rather than this.defineProperty() (for objects)?

I'm working on a JavaScript project, and was just wondering why an object instance doesn't inherit the defineProperty() and other methods, rather than having to call the superclass (superobject?) Object method.
I've looked at the MDN docs, and there are in fact "non-standard" property methods.
But those are deprecated. Why would the move be to the Object methods?
It seems to me that something like instance.defineProperty(...) is better than Object.defineProperty(instance, ...). I would say the same about some of the other Object methods as well.
It's to avoid collisions - in general, issues with objects that do not have the property with the value that you expect.
Objects in JS are often used as key-value-maps, and the keys can be arbitrary strings - for example __defineGetter__, hasOwnProperty or something less special. Now when you want to invoke such a function on an unknown object - like hasOwnProperty is often used in generic enumeration functions, where any JSON might be passed in - you can never be sure whether you got a overwritten property (that might not even be a function) or the original which you want, or whether the object inherits the property at all. To avoid this issue (or also this IE bug), you'd have to use Object.prototype.hasOwnProperty.call - that is ugly.
So, namespacing all those functions on Object is only useful, it's a cleaner API that separates the reflection methods from the object's application interface. This also helps optimisation (simplifying static analysis) and makes it easier to restrict access to the reflection API in sandboxes - at least that was the design idea.
You might be happy to have a defineProperty around in the prototype, but you can only use it safely when working with known objects. If you still want it (as you know when to use and when not), you could use
Object.defineProperty(Object.prototype, "defineProperty", {
writable: true,
enumberable: false,
value: function(prop, descr) {
return Object.defineProperty(this, prop, descr);
}
});
It's done like that to avoid collisions - remember, every method on Object.prototype is a method in every single user-defined object, too.
Imagine an object where you'd want a custom method defineProperty - that would completely break things when Object.defineProperty was on its prototype instead.
Interesting. The only reason I came up with so far is that people like to rewrite the prototypes and having this method "hidden" like this might help you avoid some bugs. Especially because of the good method name since that is more likely to get rewritten than, for example, __defineGetter__.
It seems that a lot of features depend on this functionality (link), so it makes sense to make it more global and secure in this context.

Categories

Resources