2015-07-04 53 views
0

在下面的代碼中,當我執行跟蹤函數並將變量「original」分配給最初未定義的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 

當標識符引用了對象它引用相同的對象,而不是一個副本,因此它所做的更改影響他們所有。這是因爲你所訪問的對象與標識符而不是對象的財產,即e === o

如果你要再做o = fizzo現在指向一個不同的東西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如果你在'o = fizz' **之後做了'e = o' **或**'e =發出嘶嘶聲,你會有三個指向同一個東西。這只是你必須手動更新每個標識符。另外,'e.prop()'不應該在我寫的代碼中拋出錯誤。 **'o.prop()'**在關於'fizz'的節中拋出一個錯誤。 –

相關問題