【发布时间】:2011-12-08 01:22:56
【问题描述】:
更新:由于这个问题没有答案,我稍微改变一下这个问题。对下面链接的 Dean 博客上的帖子的评论表明,这种技术在 Safari 中不起作用。
我现在的问题是:下面描述的技术在现代浏览器中是否有效*,尤其是有人可以确认它在 Safari 中是否有效吗?
这是更新的blog post。它在某一时刻说:
Sandboxed natives ... 支持多种浏览器,包括 ... Safari 2.0+
...但后来表示 iframe 技术“被所有主流浏览器支持,除了 Safari”,他展示的后备方案涉及使用伪造的构造函数和 __proto__ 做一些奇怪的事情,这似乎有点 hacky。
我几乎很难相信两个不同的窗口实际上可以共享同一个,比如 Object.prototype。跨域 iframe 会发生什么?如果我修改一帧中的原型,是否修改另一帧中的原型?这似乎是一个明显的安全问题。有人请阐明这种情况。
* “工作”是指My.Object != Object,因此可以在一个窗口中修改原型而不影响另一个窗口。
原帖
我知道以前有人问过这个问题,但我有一个具体的解决方案,我想知道以前是否讨论过这种类型的解决方案,以及我可以从哪里了解到它的可靠性和被广泛接受的程度。
问题是如何在 javascript 中扩展原生类型,而不会真正弄乱类型本身,所以仅仅改变 Array.prototype 是不好的(也许其他代码正在使用 for..in 和数组)。创建一个返回带有一些附加功能的本机数组的假构造函数似乎也不是一个好的解决方案,实际上扩展本机对象似乎更好。但是你也不能用原生类型做普通的 javascript 虚拟函数原型 switcharoo 样式扩展,因为当你尝试调用原生函数时,你会得到像“push is not generic”这样的错误。
所以,我想到的解决方案是这样工作的:创建另一个窗口,在该窗口中向本机构造函数的原型添加功能,然后在程序中使用这些构造函数。
此示例将Array 扩展为具有each 函数的My.Array,并将String 扩展为具有My.String 的My.String 函数。
var My = (function(){
// create an iframe to get a separate global scope
var iframe = document.createElement('iframe');
iframe.style.height = '0px';
iframe.style.width = '0px';
iframe.style.border = 'none';
iframe.style.position = 'absolute';
iframe.style.left = '-99999px';
document.documentElement.appendChild(iframe);
var My = iframe.contentWindow;
My.String.prototype.alert = function(){
alert(this);
}
My.Array.prototype.each = function(callback){
for (var i=0, l=this.length; i<l; i++) {
callback(this[i], i);
}
}
return My;
}());
再次,我的问题是这种方法之前是否已经讨论过,它叫什么,我可以在哪里找到更多信息等。我想知道是否有一种更简洁的方法可以在不使用 iframe 的情况下获得另一个全局范围,或者如果在某些 javascript 引擎中由于某种原因这可能会失败,或者如果有人认为这是一个特别糟糕的主意或其他什么。
更新:我猜人们将这种东西称为 iframe 沙箱,不要与 HTML5 iframe 沙箱属性混淆。
相关:
http://dean.edwards.name/weblog/2006/11/hooray/
http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html
【问题讨论】:
-
获得一个干净的窗口对象是对 iframe 的合法使用,尽管这种技术最常用于摆脱那些额外的方法,然后添加它们......跨度>
-
missingno,您知道目前使用这种技术的任何事情吗?它有很多奇怪的后果,我想如果它被使用的话,一定会有一些关于它的邮件列表讨论
-
我记得读过一个来自 Disqus 的人的presentation。他们使用这种技巧是因为他们需要能够将代码嵌入到任何地方。
-
谢谢,很好的介绍。扩展本机类型的好处是它很有用,但很烦人。这种技术对于命名空间扩展的东西似乎和它在当前窗口中处理扩展的东西一样好。不过,iframe hack 很丑陋。 typeof 也始终是 object,而 My.Array 不是 instanceof Array。
-
如果你只是想在你的函数中使用
this,你可以使用call或apply。
标签: javascript iframe constructor safari