2016-10-01 162 views
0

我想更改分配給window.location的所有鏈接。所以我認爲location有getter &二傳手。這就是爲什麼我克隆它&然後我覆蓋了真正的window.location無法覆蓋window.location的setter&getter

var clonedLocation=Object.assign({},window.location); 


      Object.defineProperty(window, 'location', { 
       get: function (f) { 
       return clonedLocation; 
       }, 
       set:function(o){ 
       if(typeof o==='string'){ 
        o=o+'?id=1'; 
       } 
       clonedLocation=o; 
       } 
      }); 

     }; 

預期的行爲(如果中重寫完成的),當你寫:

window.location='/go'; 

腳本應該重定向到/go?id=1/go

但是實際的行爲是此腳本重定向到/go

==>因此,window.location制定者並沒有覆蓋,

如何覆蓋的window.location二傳手?

+1

見http://stackoverflow.com/questions/2073086/javascript-how-to-intercept-window-location-change – guest271314

回答

1

Javascript properties can be defined to have configurable: false表明它們不能被重新定義。

嘗試重新定義這些財產會導致類似的錯誤:

Uncaught TypeError: Cannot redefine property: location 

這是可以預料,在主機對象的屬性是不可配置出於安全原因。

Property descriptor for location

+0

其實,作爲一個*主機對象*屬性它甚至不需要它的配置' ''屬性被設置爲'false',因爲行爲不可預測。 – Bergi

+0

是的 - 非常真實。與這個特定的問題並不真正相關,但是通過一種通用的方法來檢測屬性是否可配置(哪些主機對象也遵守)有助於消費者代碼使用反射來檢測可配置性,而不是必須特殊處理所有主機對象。 – lorefnon

0

你用來包裹window.location的與可以實現鉤(前後)另一靜態類:

您可以通過檢查的屬性描述符驗證這一點看看到kaop

Aspects.add(
    function op1(){ 
    console.log("operation one"); 
    var argument0 = meta.args[0]; 
    if(typeof argument0==='string'){ 
     argument0=argument0+'?id=1'; 
    } 
    }, 
    function op2(){ 
    console.log("operation two"); 
    } 
) 

var DummyLocation = Class({ 
    set: ["op1", function(newUrl){ 
    location = newUrl; 
    }, "op2"], 
    get: [function(){ 
    return location; 
    }] 
}) 

現在,你應該使用:

DummyLocation.set("/go");