Identifiers don't update when you change the source you used to set them.
var o = {prop: function () {return 'old ref';}};
var foo = o.prop; // foo() === "old ref"
o.prop = function () {return 'new ref';};
foo(); // "old ref"
However, it may also be worth noticing
var e = o; // o as before
o.prop = function () {return 'even newer ref';};
e.prop(); // "even newer ref"
e === o; // true
When the identifier references an Object it's referencing the same object and not a copy, so changes made to it effect them all. This is because you're accessing the Object with the identifier rather than the property of that Object, i.e. e === o
If you were to then do o = fizz, o now points to a different thing to e so e !== o
var fizz = {buzz: "I'm something new!"};
o = fizz;
e.buzz; // undefined, e points at {prop: function () {...}}, not fizz
o.prop(); // TypeError, o points at fizz, not e
o.buzz; // "I'm something new!"
e === o; // false
fizz === o; // true
Lastly, by looking over what you were attempting to do you may need to consider "was there anything before?". This is why your code is throwing an Error currently.
function change(obj, prop, echo) {
var prev_method = obj[prop];
obj[prop] = function () {
if (prev_method) // only if we had something before
prev_method.apply(this, arguments); // try to invoke it
console.log(echo);
};
}
var o = {};
change(o, 'spell', 'H');
change(o, 'spell', 'e');
change(o, 'spell', 'l');
change(o, 'spell', 'l');
change(o, 'spell', 'o');
o['spell'](); // returns undefined, logs H, e, l, l, o