50

我可以在 javascript 中向“窗口”对象添加任何随机属性吗?就像是:

window.my_own_attr = "my_value"

它对任何库有任何副作用吗?它是否跨浏览器兼容?

4

7 回答 7

73

我可以在 javascript 中向“窗口”对象添加任何随机属性吗?

是的,就像你展示的那样。

它对任何库有任何副作用吗?

不,除非您使用设置了然后覆盖的属性的库。

它是否跨浏览器兼容?

是的,完全。


话虽如此,这种做法通常是不受欢迎的。你最终可能会覆盖你不想覆盖的东西。

于 2012-10-05T09:06:38.337 回答
15

所有浏览器中,window是 javascript 全局命名空间。每个属性或方法都“存在”在该命名空间中。因此,如果您将属性分配给window,它实际上是一个全局变量

例子:

window.myConstant = 5;

// note: a var declaration will be a window property too
// note 2: 'let' or 'const' will not be window properties
// below can also be done without 'var'.
var myConstantGlobal = 4;

console.log(`multiply(10) => ${multiply(10)}`);
console.log(`multiply() => ${multiply()}`);
console.log(`multiplyGlobalVar(10)) => ${multiplyGlobalVar(10)}`);
console.log(`multiplyGlobalVar() => ${multiplyGlobalVar()}`);
    
function multiply(val){
  return myConstant * (val || 1);
}

function multiplyGlobalVar(val){
  return window.myConstantGlobal * (val || 1);
}

您必须谨慎使用 javascript 框架。例如,如果您声明window.JQuery并使用JQuery框架,JQuery命名空间将被您的分配替换,使其无用。

于 2012-10-05T09:13:54.570 回答
4

是的,你可以,但一般来说你不应该。

window对象也是 JS 默认的“全局”对象,因此所有全局变量都被添加到那里。

除非您覆盖已经存在的属性,否则您不太可能破坏任何东西,但是将变量转储到 上window或以其他方式创建大量全局变量被认为是不好的做法。

于 2012-10-05T09:06:48.310 回答
4

我不会重复其他人所说的:这种做法的 hackyness。但是当使用像 Angular 这样的刚性框架与普通 HTML / JS(或 jQuery)代码混合时,它会非常有用。这也是 hacky 和不赞成的,但有时有充分的理由,比如如果你有很多预先存在的 JS 代码,这些代码很难集成到框架中。

对我来说更有趣的问题是如何利用向全局window对象添加属性的能力。当我想将 Angular 提供程序(服务)的方法公开给无法注入服务的代码时,我使用了一种模式,这可能是因为它在 Angular DI 框架之外运行。我这样做的方式如下:

  1. 将您的服务定义为顶级模块中的提供者。
  2. 在 app.component.js 的构造函数或 onInit (或导入提供程序的任何顶级组件)中,正常注入提供程序,执行它需要的任何一次初始化,然后调用window['MyServiceName'] = this

假设您将提供程序设计为遵循单例模式,您的提供程序的方法现在可以从任何地方安全地调用。非 Angular 脚本只需调用window['MyServiceName'].methodName()

于 2018-02-16T15:07:48.927 回答
1

在 IE 中,如果元素具有 id,则该节点可作为属性在窗口对象上访问:

<div id="num"></div>

alert(num); //Element

num = 3; //throws exception

var num = 3; //ok

于 2012-10-05T10:39:44.717 回答
0

这会正常工作,在使用相同的变量名之前不会与任何库冲突,将在所有浏览器中工作,但不推荐,因为这会创建全局 JS 变量。

于 2012-10-05T09:08:00.380 回答
-1

正如其他人所指出的,是的,你可以,是的,这意味着添加“全局变量”。

拥有全局变量不是最佳实践,但有时它是最简单的事情。例如,如果您使用 IFrame 并希望子窗口访问父窗口的某些属性。这样的属性必须是“全局的”,孩子才能访问它。但这也表明它不是“真正的全局”,它只是特定窗口的属性。但它可能与其他属性名称冲突,例如在同一窗口中定义的函数名称,可能是您使用的某些库。

所以我们知道全局变量是不好的。如果我们决定使用它们,我们能做些什么来减少它们的坏处吗?

是的,有:定义一个具有或多或少唯一名称的 SINGLE 全局变量,并将 OBJECT 存储到其中。将您需要的所有其他“变量”存储为该单个对象的字段。

这样您就不需要添加多个全局变量(每个窗口)。还不错。

命名它或多或少是唯一的,因此它不太可能与其他任何人的单一全局冲突。例如,您可以使用 name + 's' 作为变量名:

window.Panus  = {}; 

:-)

于 2018-11-19T15:31:31.093 回答