在 JavaScript 函数中定义全局变量

IT技术 javascript function variables scope declaration
2021-01-20 05:43:40

是否可以在 JavaScript 函数中定义全局变量?

我想在其他函数中使用trailimage变量(在makeObj函数中声明)。

<html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script type="text/javascript">
            var offsetfrommouse = [10, -20];
            var displayduration = 0;
            var obj_selected = 0;
            function makeObj(address) {
                **var trailimage = [address, 50, 50];**
                document.write('<img id="trailimageid" src="' + trailimage[0] + '" border="0"  style=" position: absolute; visibility:visible; left: 0px; top: 0px; width: ' + trailimage[1] + 'px; height: ' + trailimage[2] + 'px">');
                obj_selected = 1;
            }

            function truebody() {
                return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
            }
            function hidetrail() {
                var x = document.getElementById("trailimageid").style;
                x.visibility = "hidden";
                document.onmousemove = "";
            }
            function followmouse(e) {
                var xcoord = offsetfrommouse[0];
                var ycoord = offsetfrommouse[1];
                var x = document.getElementById("trailimageid").style;
                if (typeof e != "undefined") {
                    xcoord += e.pageX;
                    ycoord += e.pageY;
                }
                else if (typeof window.event != "undefined") {
                    xcoord += truebody().scrollLeft + event.clientX;
                    ycoord += truebody().scrollTop + event.clientY;
                }
                var docwidth = 1395;
                var docheight = 676;
                if (xcoord + trailimage[1] + 3 > docwidth || ycoord + trailimage[2] > docheight) {
                    x.display = "none";
                    alert("inja");
                }
                else
                    x.display = "";
                x.left = xcoord + "px";
                x.top = ycoord + "px";
            }

            if (obj_selected = 1) {
                alert("obj_selected = true");
                document.onmousemove = followmouse;
                if (displayduration > 0)
                    setTimeout("hidetrail()", displayduration * 1000);
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <img alt="" id="house" src="Pictures/sides/right.gif" style="z-index: 1; left: 372px;
            top: 219px; position: absolute; height: 138px; width: 120px" onclick="javascript:makeObj('Pictures/sides/sides-not-clicked.gif');" />
        </form>
    </body>
</html>
6个回答

正如其他人所说,您可以var在全局范围内(在所有函数和module之外)使用来声明一个全局变量:

<script>
var yourGlobalVariable;
function foo() {
    // ...
}
</script>

(请注意,这仅适用于全局范围。如果该代码在module中 — <script type="module">...</script> — 它不会在全局范围内,因此不会创建全局。)

或者:

在现代环境中,您可以为globalThis引用的对象分配一个属性globalThis在 ES2020 中添加):

<script>
function foo() {
    globalThis.yourGlobalVariable = ...;
}
</script>

在浏览器上,您可以使用名为 的全局变量执行相同的操作window

<script>
function foo() {
    window.yourGlobalVariable = ...;
}
</script>

...因为在浏览器中,所有用全局变量声明的全局变量var都是window对象的属性(在最新的规范 ECMAScript 2015 中,全局范围内的 new letconstclass语句创建了不是全局对象属性的全局变量;ES2015 中的一个新概念。)

(还有隐式 globals 的可怕之处,但不要故意这样做,并尽量避免意外这样做,也许是使用 ES5 的"use strict".)

所有这一切都说:如果可能(而且几乎可以肯定),我会避免使用全局变量。正如我所说,他们最终会被的性能window,并且window已经大量拥挤够什么用的所有元素的id(和许多只用name),它被倾倒(且不论是即将到来的规范,IE转储只是用什么name在那里)。

相反,在现代环境中,使用module:

<script type="module">
let yourVariable = 42;
// ...
</script>

module中的顶级代码位于module范围内,而不是全局范围内,因此会创建一个该module中的所有代码都可以看到的变量,但这不是全局的。

在没有module支持的过时环境中,将代码包装在作用域函数中并使用该作用域函数的局部变量,并在其中关闭其他函数:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>
@CasparKleijne,我不明白。当您确实没有证据表明 window 对象确实存在时,为什么要在 window 上分配它。您对将来如何使用您的代码一无所知。它甚至可能用于 MongoDB 环境或 rino 而不是您的节点。例如,如果您使用 Web Worker,即使在浏览器中也看不到 window 对象。这将完全扼杀可重用性。
2021-03-16 05:43:40
请注意,使用window在 Node.js 中不起作用。这里最简单的技巧是设置:GLOBAL.window = GLOBAL;--正如在这个相关问题中所解释的当然,这在概念上并不完全。我更喜欢以GLOBAL相反的方式做事,所以我可以使用代替window.
2021-03-27 05:43:40
window.yourGlobalVariable = ...; 在堆栈站点上阅读 5 到 6 个问题后,就像一个魅力。
2021-03-27 05:43:40
@JacquesKoekemoer:没有任何理由在eval那里使用反而:window[dynamic_variable_name] = dynamic_variable_value;
2021-03-27 05:43:40
@AstritSpanca - 这就是我在答案中间的括号中提到的隐式全局变量的可怕之处:-)
2021-03-31 05:43:40

只需声明

var trialImage;

外部。然后

function makeObj(address) {
    trialImage = [address, 50, 50];
    ...
    ...
}

如果您阅读评论,就会对这个特定的命名约定进行很好的讨论。

似乎自从我的答案发布以来,命名约定变得更加正式。教书、写书等的人讲var宣言,function宣讲宣言。

这是支持我的观点的额外维基百科帖子:声明和定义 ......并回答主要问题。在函数之前声明变量。这将起作用,并且符合在范围顶部声明变量的良好做法:)

@Stuntddude你可能是对的:(我开始回答这个问题,然后决定有点分歧,这就是我们所得到的。仍有一些人仍然觉得它很有用,所以我把它留在这里。谢谢你回馈!
2021-03-11 05:43:40
如果您想在别处定义变量,请务必了解提升是什么。这是一篇关于它的非常好的文章enoughlygood.com/2010/2/JavaScript-Scoping-and-Hoisting祝你好运!
2021-03-20 05:43:40
这无助于回答问题。它应该是评论,而不是答案。
2021-03-31 05:43:40
这不是什么definitiondeclaration意味着C.你的第一行可以是一个声明或定义(这取决于它在哪里); 第二个只是一个任务。声明只是指定标识符的解释(即myVar是一个int);如果声明保留存储,则为definition. 这与打字无关;这是编译单元如何理解对其他编译单元的引用的一部分。
2021-04-02 05:43:40
即使是在JS,var myVar被称为声明(它不需要键入)和myVar = 10一个分配我听说过化合物 ( var myVar = 10;) 的“定义”一词
2021-04-07 05:43:40

只需在函数外声明它,并在函数内赋值。就像是:

<script type="text/javascript">
    var offsetfrommouse = [10, -20];
    var displayduration = 0;
    var obj_selected = 0;
    var trailimage = null ;  // Global variable
    function makeObj(address) {
        trailimage = [address, 50, 50];  // Assign value

或者简单地从函数内部的变量名中删除“var”也会使其成为全局变量,但为了更简洁的代码,最好在外部声明一次。这也将起作用:

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;

function makeObj(address) {
    trailimage = [address, 50, 50];  // Global variable, assign value

我希望这个例子能解释更多:http : //jsfiddle.net/qCrGE/

var globalOne = 3;
testOne();

function testOne()
{
    globalOne += 2;
    alert("globalOne is :" + globalOne );
    globalOne += 1;
}

alert("outside globalOne is: " + globalOne);

testTwo();

function testTwo()
{
    globalTwo = 20;
    alert("globalTwo is " + globalTwo);
    globalTwo += 5;
}

alert("outside globalTwo is:" + globalTwo);
非常干净和有效的解决方案 +1
2021-04-02 05:43:40

不,你不能。只需在函数外声明变量即可。您不必在分配值的同时声明它:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];
@mustafa.0x:你错了。您不能在函数内定义全局变量。您可以隐式创建全局变量,或者在函数内部创建窗口属性,但不能在函数内部定义全局变量。
2021-03-13 05:43:40
如果您不使用严格(但为什么不使用严格?),您实际上可以 通过违背所有良好做法而在函数内声明和定义全局变量,而只是不使用var,这就是 Guffa隐式创建的意思(例如@DhruvPathak 也指向那里)。
2021-03-20 05:43:40
对不起!“是否可以在 JavaScript 函数中定义全局变量?” -- “不,你不能”是不正确的,正如第一个答案所示!
2021-04-02 05:43:40
对于浏览器环境中的 JavaScript,全局变量和属性window是同义词。无论哪种方式,您所做的语义区分都很清楚,所以我不介意取消投票。编辑:无法更改我的投票,抱歉!
2021-04-03 05:43:40