我是JavaScript的初学者,正在尝试理解JavaScript中的全局window对象。所以,如果我只想象我在控制台写的任何代码,例如var text = "Hello"; console.log(text)
被放置在window对象中,如此引用window对象:window{var text = "Hello"; console.log(this.text)}
。如果我这样考虑,可以吗?还是不正确的?谢谢
我是JavaScript的初学者,正在尝试理解JavaScript中的全局window对象。所以,如果我只想象我在控制台写的任何代码,例如var text = "Hello"; console.log(text)
被放置在window对象中,如此引用window对象:window{var text = "Hello"; console.log(this.text)}
。如果我这样考虑,可以吗?还是不正确的?谢谢
做出关于global
对象或默认的this
上下文的假设并不十分安全,因为它可能因javascript运行时的不同而有所变化,而一些功能,例如严格模式也会改变这种行为。
请记住,javascript不仅在浏览器中运行-例如在node.js中的全局与在浏览器中的不同-,而且有很多不同的浏览器实现。
此外,在某些环境中,默认情况下var
确实会写入全局,但是const
和let
则不会。
在node中,自由调用函数而没有先前的引用将无法从global
调用它们,而是会失败。这也严重影响了前端代码,因为现在许多面向浏览器的javascript都是通过webpack等在node环境中预编译的。
简而言之,通常很难假设关于global
、window
和默认的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();
"使用全局对象是否可以?"
当然可以。如果你知道其中的陷阱,并且是有目的地而不是偶然地使用全局对象。
(function() {
name = 12; // Note: This *is* a global variable
console.log(typeof name); // string. WTF
})();
这些陷阱包括:
1)所有未声明的变量和使用var
声明的全局变量都会自动成为全局对象的一部分。这是不好的,因为这种情况会在没有任何充分理由的情况下发生,所以应该避免这种情况(使用严格模式和let
和const
)。
2)您运行的所有脚本都具有相同的全局对象,因此属性可能会发生冲突。这就是上面示例中发生的情况,name
与全局window.name
getter / setter对冲突,将数字转换为字符串。因此,如果在全局对象中设置属性,请确保名称仅由您使用,而不是由其他人(浏览器、库、其他代码片段)使用。
如果您了解这些陷阱并避免它们,您可以而且应该有目的地使用全局对象,仅当您计划在页面上的不同脚本之间共享某个函数/变量时,因此如果它确实应该是全局可访问的。
let private = 1;
window.shared = 2;
var foo = "foobar";
foo === window.foo; // Returns: true
function greeting() {
console.log("Hi!");
}
window.greeting(); // It is the same as the normal invoking: greeting();
var text
想象成总是属于window
的东西。如果你想要的话,可以在这里尝试一下:https://jsfiddle.net/rpkgewz3/ - brioshejewindow
对象只存在于浏览器中,但 JavaScript 在所有环境中都有一个全局对象,并且其行为相同。 @mirzhal 是的,您可以将顶级声明视为全局范围的属性,但最好采纳 @Quentin 的建议。 - Robbie Milejczakwindow
被填充的情况非常广泛。它在很大程度上取决于脚本环境,如果是在浏览器中,则取决于它是在头部还是在主体中。 - briosheje