为什么添加到一个IFRAME的String.prototype中的属性在使用IFRAME的String函数创建的字符串对象中不可用?

时间:2013-01-16 16:47:21

标签: javascript gwt iframe prototype

我正在开发一个GWT项目,其中主机页面具有向String.prototype添加属性的脚本。主页页面脚本依赖于这些属性的存在才能正确运行,因此我需要确保每当我将一个字符串从GWT传递给"主机代码"时,额外的属性都存在于对象中

我认为通过在非构造函数上下文中调用$wnd.String,额外的属性就在那里,但事实并非如此。在这个模拟GWT设置中,例如:

test.html

<!DOCTYPE html>
<html>
<head>
<script>

String.prototype.myStartsWith = function String_myStartsWith(prefix) {
    prefix = String(prefix);
    return (this.indexOf(prefix) === 0);
};

function onLoad() {
    var iframe = document.createElement("IFRAME");
    iframe.src = "javascript:''";
    iframe.id = "myFrame";
    document.body.appendChild(iframe);
    iframe.contentWindow.location.replace("myFrame.html");
}

</script>
</head>
<body onload="onLoad()">
</body>
</html>

myFrame.html

<!DOCTYPE html>
<html><head><script>

var $wnd = parent;
var $doc = $wnd.document;

debugger;

</script></head></html>

当执行命中debugger行时,使用JS调试器控制台获得以下结果:

> $wnd.String !== String
true

> new $wnd.String("test").myStartsWith === undefined
false

> $wnd.String.prototype.myStartsWith === undefined
false

> $wnd.String("test").myStartsWith === undefined
true

Firefox 18.0,Safari 6.0.2和Opera 12.12中的结果相同。

前三个是预期的,但我不希望第四个检查$wnd.String("test").myStartsWith === undefinedtrue

为什么myStartsWith在非构造函数上下文中调用$wnd.String返回的字符串对象中不可用?

2 个答案:

答案 0 :(得分:3)

  

为什么myStartsWith在非构造函数上下文中调用$wnd.String返回的字符串对象中不可用?

因为non-constructor String function只应用ToString并返回原语字符串值。如果访问该属性,则使用当前全局上下文的String构造函数 - 没有修改原型的那个。所以

$wnd.String("test").myStartsWith

评估为

"test".myStartsWith

并且相当于

new String($wnd.String("test")).myStartsWith

当然是undefined

答案 1 :(得分:0)

我想答案(不确定gwt是如何工作的)

您正在更改不同窗口上的原型

然后:

    var iframe = document.createElement("IFRAME");
    iframe.id = "myFrame";
    document.body.appendChild(iframe);
    iframe.onload = function(){

         // here is the correct prototype
         this.contentWindow.String.prototype.myStartsWith =
                    function(){ alert("hello"); };

    }
    iframe.src = "myFrame.html";