Javascript - Difference between defineProperty and directly defining a function on an object - javascript

I recently created my own module for node.js for use with the koa module. It's a translation module like koa-i18n. I've studied other koa modules to see how functions/properties are applied to the koa context/request and some of them use the Object.defineProperty function, but what I did in my module was apply a function directly on 'this'.
So, what is the difference between using
Object.defineProperty(app.context, 'getSomeValue', { ... });
and
return function* (next) { this.getSomeValue = function () { ... } }
I've also come across the node-delegates module which uses the 'apply' function.
Which of these methods is the preferred way of applying a function/property to an existing object and what are the pros and cons?

The defineProperty method has specific advantages over directly setting a property in an object or returning a function object (which in some ways can simulate pesudo-private fields).
You can use defineProperty to define constants decide whether they are enumerable and more.
You can check-out a similar discussion here - when do you use Object.defineProperty().
Also do check out the examples from Mozilla Developer Network for this method and the configs for being able to decide whether the prop is writable, enumerable etc using define property.
Apply is a bit different and I think a better comparison would be with the JavaScript call method. It is similar to call with mostly schematic differences. See note here. Apply and Call can be used in a way to invoke a method - roughly like reflection in other languages like Java.

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.

using .call vs. passing "this" in JavaScript

I know that if you have some javascript function and you want to call it such that using this within it would refer not to the object on which it was directly called you can use func.call(thatObject,param,and,more,params...).
But suppose you are the writer of func and the only usage for func is via func.call,
Why would you not define it to begin with as:
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
yep, it looks less "cool" because its not a method of an object,
but hey if the only usage for func is via func.call it all seems like just extra code and overhead.
Am I missing something here? or is the source code in which I have seen this pattern just "over OOed" ?
There appears to be a large performance difference. Using
func(){
//code here, this.something
}
func.call(thatObject)
according to the first couple of tests is about 8 times slower than using
func(that){
//code here, that.something
}
func(thatObject)
Test it yourself, JSPerf here
Ultimately though, speed alone is rarely the most important factor in which code we use. Code is designed for people as much as it is for computers, we need to communicate our intentions clearly to both. Whichever makes the code cleanest is best, and we should follow conventions whenever it is feasible. I personally prefer the second option here, but I think the general convention is the first. So I think you use call in most situations, except for when you need the fastest code possible or if the convention changes.
Your pattern will work in this scenario but in general it has some problems ...
Constructor functions -> We create objects by using new keyword where 'this' object is automatically created and returned (default) also has the link with the function's prototype.
When calling the function someone might forget to pass 'that' object and your code will fail. In case of call if you pass null it is reset to global object (non-strict mode which is common)
func.call is intended to be used when an alternative (or any) context for the function is needed to be provided.
Your suggestion is odd, since, when you define the function using this pattern:**
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
it's either:
doesn't belong to any object
in which case passing an object to act as this doesn't make any sense, since there should be no this.someThing calls to begin with
or belongs to a different object or is defined to be a plug to an object
in which case it does exactly what func.call would do, while contaminating the definition of the function with redundant parameter.
UPDATE:
Think of the second example in this way - imagine that some set of Objects (what you'd call from the same "class") allow injection of arbitraty functions, say for iteration over all properties of the object and some summary or manipulation or what have you.
In Java, the common pattern is to create an Iterator and pass it, and its main purpose is to serve as sort of placeholder so that next and hasNext methods can be called - since Java doesn't really have object-less functions. (granted there is some additional logic there, but let's leave it alone for the sake of this discussion).
JavaScript does not neeed this! All these call and apply methods do not need to have some additional Iterator object to hold them. They can be defined "detached" from any object, while still with intention to be used in a context of one (hence this usage in their code) and injected into code that knows to accept such functions.
The "host" code than only needs to call or apply them, knowing that this will refer to itself - this very "host" object.
This leads to a more concise, reusable and portable code, IMO.
UPDATE 2:
See more here.

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.

Add a JavaScript getter/setter to a native unconfigurable property

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

Categories

Resources