2016-10-01 168 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");