简体   繁体   中英

JavaScript variable is undefined even after assigning an object property method

In the following code when I execute trace function and the variable "original" gets assigned to o[m] which is undefined initially but once I define o[m] as a nested function inside trace and trace function returns I expect that value of "original" variable should be newly defined nested function but to my surprise it is still undefined. I can't understand why?

   var o = {};            
   function trace(o, m) {
   var original = o[m]; 
   o[m] = function () { 
    alert(new Date(), "Exiting:", m);
    var result = original.apply(this, arguments); 
    alert(new Date(), "Exiting:", m); 
    alert(result); 
 };
}

 trace(o, "m");
 o.m("My JavaScript");

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 , ie 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM