JavaScript中关于全局对象的混淆
我是JavaScript的初学者,我试图理解JavaScript中的全局窗口对象。那么,如果我只是想象一下我在控制台中编写的任何代码,比如JavaScript中关于全局对象的混淆,javascript,Javascript,我是JavaScript的初学者,我试图理解JavaScript中的全局窗口对象。那么,如果我只是想象一下我在控制台中编写的任何代码,比如var text=“Hello”;console.log(text)放在窗口对象中,就像下面这个引用窗口对象的窗口{var text=“Hello”;console.log(this.text)}。如果我这样认为还是不正确,可以吗?谢谢是的,可以从窗口对象示例访问任何函数或变量: var foo = "foobar"; foo === window.foo;
var text=“Hello”;console.log(text)
放在窗口对象中,就像下面这个引用窗口对象的窗口{var text=“Hello”;console.log(this.text)}。如果我这样认为还是不正确,可以吗?谢谢是的,可以从窗口对象示例访问任何函数或变量:
var foo = "foobar";
foo === window.foo; // Returns: true
function greeting() {
console.log("Hi!");
}
window.greeting(); // It is the same as the normal invoking: greeting();
假设全局
对象或默认的此
上下文是不安全的,因为它可能会因javascript运行时的不同而有所不同,并且一些特性(如)也会改变这种行为
请记住,javascript不仅在浏览器中运行——例如node.js中的全局运行与在浏览器中的运行不同——而且还有许多不同的浏览器实现
此外,虽然在某些环境中,var
默认情况下会写入全局,但const
和let
则不会
在节点中,在没有先前引用的情况下自由调用的函数不会从全局调用它们,而是会失败。这也严重影响了前端代码,因为现在浏览器的大部分javascript都是通过webpack等在节点环境中预编译的
因此,简而言之:通常很难假设有关global
、window
和default的事情,并正确地进行绑定假设您没有可用的默认全局对象,并且总是显式地引用窗口
,可能更安全一些,如下所示:
config.js
window.config = {foo: 'bar'}
window.someGlobalFunction = function() {...}
// do:
const elen = new User(window.config);
window.someGlobalFunction();
// don't
const elen = new User(config);
someGlobalFunction();
user.js
window.config = {foo: 'bar'}
window.someGlobalFunction = function() {...}
// do:
const elen = new User(window.config);
window.someGlobalFunction();
// don't
const elen = new User(config);
someGlobalFunction();
“可以使用全局对象吗?”
当然是。如果您知道这些陷阱,并且出于目的而不是偶然地使用全局对象
陷阱是:
1) 所有未声明的(!)变量和使用var
声明的全局变量都会自动获取全局对象的一部分。这是不好的,因为这种情况的发生没有任何好的理由,所以你应该避免(使用,和)
2) 您运行的所有脚本都具有相同的全局对象,因此属性可能会发生冲突。这就是上面示例中发生的情况,name
与将数字转换为字符串的全局window.name
getter/setter对冲突。因此,如果在全局对象中设置属性,请确保该名称仅由您使用,而不是由其他人使用(浏览器、库、您编写的其他代码段…)
如果您知道并避免了这些缺陷,那么您可以并且应该有目的地使用全局对象,如果并且仅当您计划在页面上的不同脚本之间共享某个函数/变量,那么它是否应该是全局可访问的
关于全局对象的更多信息,您可以在这里阅读,不要让全局对象困扰您。javascript可以在不同的环境中运行。所以不要忘记,您的问题仅在browsersEnable strict模式下有效。关于你的句子,不,你不能想象var text
总是属于window
。如果你想玩的话,可以玩一下:@AntonHolmberg我知道,这是为了证明有一个非常广泛的场景,关于窗口如何填充。这在很大程度上取决于脚本环境,如果它在浏览器中,无论是在头部还是在身体中。C,我可以想象上面的代码就像Window{var foo=“foobar”;function greeting(){console.log(“Hi!”);}greeting();}想象一下Window对象就像一个巨大的袋子,我们编写的任何代码都放在里面。可以吗?客户端代码在节点中预编译并不意味着它在节点上运行。这一部分可能更清楚。