2015-07-04 1 views
0

В следующем коде, когда я выполняю функцию трассировки, а переменная «оригинал» присваивается o [m], которая не определена первоначально, но как только я определяю o [m] как вложенная функция внутри функции трассировки и трассировки. Я ожидаю, что значение «исходной» переменной должно быть вновь определено вложенной функцией, но, к моему удивлению, она все еще не определена. Я не понимаю, почему?Переменная JavaScript не определена даже после назначения метода свойства объекта

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"); 

ответ

4

Идентификаторы не обновляются при изменении источника, который вы использовали для их установки.

var o = {prop: function() {return 'old ref';}}; 
var foo = o.prop; // foo() === "old ref" 
o.prop = function() {return 'new ref';}; 
foo(); // "old ref" 

Однако, это также может быть стоит заметить

var e = o; // o as before 
o.prop = function() {return 'even newer ref';}; 
e.prop(); // "even newer ref" 
e === o; // true 

Когда идентификатор ссылается на объект это ссылается на тот же объект, а не копию, поэтому изменения, внесенные в него воздействовать на них все. Это потому, что вы обращаетесь к Object с идентификатором, а не свойство этого объекта , т.е. e === o

Если бы вы были тогда делать o = fizz, o теперь указывает на другую вещь e так 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 

Наконец, глядя за то, что вы пытались сделать, вам, возможно, придется рассмотреть «там что-нибудь раньше?». Вот почему ваш код бросает Ошибка.

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 
+0

Получил вас, я бы помнил это как правило, что в идентификаторах JS не обновляется. – user2913184

+0

Можете ли вы прочесть o = fizz немного больше с точки зрения кода? Спасибо за всю помощь – user2913184

+0

@ user2913184, если вы сделали 'e = o' (после' o = fizz') ** или ** 'e = fizz', тогда у вас будут все 3, указывающие на одно и то же. Вам просто нужно обновлять каждый идентификатор вручную. Кроме того, 'e.prop()' никогда не должен вызывать ошибку в написанном мной коде. ** 'o.prop()' ** выдает ошибку в разделе о 'fizz'. –

Смежные вопросы