I am wondering can we still change the function body once it is constructed ?
var O = function(someValue){
this.hello = function(){
return "hello, " + someValue;
}
}
O.prototype.hello = function(){
return "hhhhhhh";
}
var i = new O("chris");
i.hello(); // -> this still returns the old definition "hello, chris"
The javascript statement O.prototype.hello = function(){....} doesn’t override and redefine the hello function behavior. Why is that ? I know it will have a type error if you tried to reuse the parameter someValue.
// this will fail since it can't find the parameter 'someValue'
O.prototype.hello = function(){
return "aloha, " + someValue;
}
I am wondering why It allows to add function during runtime like
O.prototype.newFunction = function(){
return "this is a new function";
}
i.newFunction(); // print 'this is a new function' with no problem.
but doesn’t allow you to change the definition once it’s defined.
Did i do something wrong ? how do we override and redefine a function within a class ? and is there a way to reuse the parameter that we passed in earlier to create the object ? in this cases how do we re-use someValue if we want to extend more functions to it.
When you use
new, the value ofthisinside the constructor points to the newly created object (for more information on hownewworks, take a look at this answer and this answer). So your new instancei, has ahellofunction. When you try to access the property of an object, it walks up the prototype chain until it finds it. Sincehelloexists on the instance of the object, there is no need to walk up the prototype chain to access the version ofhellothat returnshhhhhhhh. In a sense, you have overridden the default implementation in your instance.You can see this behavior if you don’t assign
hellotothisinside your constructor:What you’re doing is kind of backwards. The prototype basically provides the “default” form of something, which you can override on a per-instance basis. The default form is used only if the property you’re looking for cannot be found on the object. That is, JavaScript will start walking up the prototype chain to see if it can find a property that matches what you’re looking for. It it finds it, it will use that. Otherwise, it will return
undefined.What you basically have in the first case is as follows:
So when you do
i.hello, JavaScript sees that there is ahelloproperty oniand uses that. Now if you didn’t explicitly define ahelloproperty, you basically have the following:What this means is that you can provide a default implementation in the prototype, and then override it (in a sense it’s like sub-classing). What you can also do is modify the behavior on a per-instance basis by directly modifying the instance. The version of
hellothat you have on the prototype is kind of a fail-safe and a fall-back.EDIT: Answers to your questions:
Overriding on a per-instance basis means you attach a property or a function to a particular instance. For example, you could do:
Which means that this behavior is specific to that particular instance (i.e., only to
iand not to any other instances that you may have created).If you take out
this, then you have basically have:Which is equivalent to doing:
So in this case,
hellois a global reference to that function. What this means is thathelloisn’t attached to any of your objects.hellocan be undefined if you don’t havethis.hello = function() { .... };inside your constructor. I was also talking about the general process that JavaScript uses to try to resolve properties on objects. As I mentioned before, it involves walking up the prototype chain.