JavaScript中关于全局对象的混淆

3

我是JavaScript的初学者,正在尝试理解JavaScript中的全局window对象。所以,如果我只想象我在控制台写的任何代码,例如var text = "Hello"; console.log(text)被放置在window对象中,如此引用window对象:window{var text = "Hello"; console.log(this.text)}。如果我这样考虑,可以吗?还是不正确的?谢谢


3
只需启用严格模式,不必担心全局对象。 - Quentin
JavaScript 可能在不同的环境中运行。因此,请不要忘记,你的问题仅适用于浏览器。 - Doğancan Arabacı
启用严格模式。关于你的句子,不,你不能把var text想象成总是属于window的东西。如果你想要的话,可以在这里尝试一下:https://jsfiddle.net/rpkgewz3/ - briosheje
@DoğancanArabacı 尽管 window 对象只存在于浏览器中,但 JavaScript 在所有环境中都有一个全局对象,并且其行为相同。 @mirzhal 是的,您可以将顶级声明视为全局范围的属性,但最好采纳 @Quentin 的建议。 - Robbie Milejczak
1
@AntonHolmberg 我知道,这证明了window被填充的情况非常广泛。它在很大程度上取决于脚本环境,如果是在浏览器中,则取决于它是在头部还是在主体中。 - briosheje
显示剩余2条评论
3个回答

1

做出关于global对象或默认的this上下文的假设并不十分安全,因为它可能因javascript运行时的不同而有所变化,而一些功能,例如严格模式也会改变这种行为。

请记住,javascript不仅在浏览器中运行-例如在node.js中的全局与在浏览器中的不同-,而且有很多不同的浏览器实现。

此外,在某些环境中,默认情况下var确实会写入全局,但是constlet则不会。

在node中,自由调用函数而没有先前的引用将无法从global调用它们,而是会失败。这也严重影响了前端代码,因为现在许多面向浏览器的javascript都是通过webpack等在node环境中预编译的。

简而言之,通常很难假设关于globalwindow和默认的this绑定的事情,并且正确地理解它们。 最好假设您没有可用的默认全局对象,并始终明确引用window,例如:

config.js

window.config = {foo: 'bar'}

window.someGlobalFunction = function() {...}

user.js

// do:
const elen = new User(window.config);
window.someGlobalFunction();

// don't
const elen = new User(config);
someGlobalFunction();

客户端代码在 Node 中预编译,并不意味着它在 Node 上运行。这一点可能需要更加清晰明确。 - Jonas Wilms

1

"使用全局对象是否可以?"

当然可以。如果你知道其中的陷阱,并且是有目的地而不是偶然地使用全局对象。

 (function() {
    name = 12; // Note: This *is* a global variable
    console.log(typeof name); // string. WTF
 })();

这些陷阱包括:

1)所有未声明的变量和使用var声明的全局变量都会自动成为全局对象的一部分。这是不好的,因为这种情况会在没有任何充分理由的情况下发生,所以应该避免这种情况(使用严格模式letconst)。

2)您运行的所有脚本都具有相同的全局对象,因此属性可能会发生冲突。这就是上面示例中发生的情况,name与全局window.name getter / setter对冲突,将数字转换为字符串。因此,如果在全局对象中设置属性,请确保名称仅由您使用,而不是由其他人(浏览器、库、其他代码片段)使用。

如果您了解这些陷阱并避免它们,您可以而且应该有目的地使用全局对象,仅当您计划在页面上的不同脚本之间共享某个函数/变量时,因此如果它确实应该是全局可访问的。

 let private = 1;  
  window.shared = 2;

0
是的,任何函数或变量都可以从window对象访问。例如:
var foo = "foobar";
foo === window.foo; // Returns: true


function greeting() {
   console.log("Hi!");
}

window.greeting(); // It is the same as the normal invoking: greeting();

C,我可以想象上面的代码就像Window对象一样{var foo = "foobar"; function greeting() { console.log("Hi!"); }greeting(); }只需想象Window对象就像一个巨大的袋子,我们编写的任何代码都会被放入其中。这样可以吗? - mirzhal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接