父框架如何访问子框架window?JS中window作用域是否为必填?
先来看你提供的代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <iframe srcdoc="<script> window.innerStr='xyz'; </script>" > </iframe> <script> function test() { let iframe = window.frames[0]; console.log('frames innerStr: ' + iframe.innerStr); // does not work if child frame says innerStr = 'xyz' without window scope } window.onload = test; test(); </script> </body> </html>
你提到的现象很典型:当子iframe里用window.innerStr='xyz'时,父框架能正常访问到这个值;但如果改成直接写innerStr = 'xyz',父框架就拿不到这个属性了。结合这个场景,我来解答你的问题:
window作用域并不是在所有JS编码场景下都必须写,但它的使用直接关系到变量的作用域范围和跨上下文的可访问性,分情况来看:
全局作用域的隐式挂载 vs 显式声明
在非严格模式下,全局作用域里直接赋值innerStr = 'xyz',其实会隐式把变量挂载到当前上下文的window对象上。理论上这种情况父框架也能通过iframe的window实例访问到,但你的例子里出现无法访问的情况,大概率是脚本执行顺序的问题——比如父框架的test()函数提前执行时,iframe里的变量还没完成赋值;或者是srcdoc这种内嵌文档的环境有特殊的隔离机制。
但如果开启了严格模式('use strict'),直接赋值未声明的变量会直接抛出ReferenceError,这时候要么显式用var/let/const声明全局变量,要么直接挂载到window上,代码才能正常运行。跨窗口/iframe的访问场景
这是你问题里的核心场景:当需要在父窗口和子窗口(或iframe)之间共享变量时,必须把变量挂载到window对象上。跨上下文访问的本质就是通过对方的window实例来获取属性,只有显式成为window属性的变量,才能被外部上下文访问到。依赖隐式全局变量的行为不仅不可靠,还容易因为环境差异或执行顺序出现问题,显式写window.xxx是更稳妥的做法。关于
window.open()的类似情况
用window.open()打开的新窗口完全遵循同样的规则:新窗口里的变量如果没有挂载到自身的window对象上,父窗口根本无法通过新窗口的window实例访问到它。只有当变量是window的属性时,跨窗口访问才能生效。
最后给个小建议:为了代码的可读性和稳定性,不管是全局变量还是需要跨上下文共享的变量,都建议显式使用window.xxx来声明或访问,避免依赖隐式挂载的行为——这能让你的代码意图更清晰,减少不必要的调试成本。
内容的提问来源于stack exchange,提问作者overexchange

