กำหนดตัวแปรโกลบอลในฟังก์ชัน JavaScript


511

เป็นไปได้หรือไม่ที่จะกำหนดตัวแปรส่วนกลางในฟังก์ชัน 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>

19
ในการประกาศคำหลักแบบโกลบอลอย่าใช้คำหลัก "var"
Ibu

20
@Ibrahim: "ประกาศทั่วโลกเพียงไม่ใช้คำหลัก" var "" Gak! สยองขวัญ ! ;-) โชคดีที่โหมดเข้มงวดไม่ได้ทำให้เกิดความสับสน
TJ Crowder

28
@Ibrahim Diallo - ไม่ใช้varไม่ได้ประกาศตัวแปรทั่วโลก ผลที่ตามมาของการกำหนดค่าให้กับตัวแปรที่ไม่ได้ประกาศคือการสร้างคุณสมบัติบนวัตถุกลางซึ่งค่อนข้างแตกต่างกันในการประกาศตัวแปร
RobG

1
ข้อมูลที่เป็นประโยชน์ในคำตอบนี้มากเกินไปstackoverflow.com/a/4862268/1356098 :)
Erenor ลาปาซ

คำตอบ:


739

ใช่อย่างที่คนอื่นพูดคุณสามารถใช้varที่ขอบเขตทั่วโลก (นอกฟังก์ชั่นทั้งหมด) เพื่อประกาศตัวแปรทั่วโลก:

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

อีกวิธีหนึ่งคุณสามารถกำหนดให้กับคุณสมบัติบนwindow:

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

... เพราะในเบราว์เซอร์ตัวแปรโกลบอลทั้งหมดตัวแปรโกลบอลที่ประกาศด้วยvarคือคุณสมบัติของwindowวัตถุ (ในสเปคล่าสุด ECMAScript ปี 2015 ใหม่let, constและclassงบในขอบเขตทั่วโลกสร้าง Globals ที่ไม่ได้คุณสมบัติของวัตถุโลก; แนวคิดใหม่ในการ ES2015.)

(นอกจากนี้ยังมีสิ่งที่น่าสยดสยองของดาราจักรโดยปริยายแต่อย่าทำอย่างตั้งใจและทำอย่างดีที่สุดเพื่อหลีกเลี่ยงการทำโดยไม่ตั้งใจโดยอาจใช้ ES5 "use strict")

ทุกอย่างที่กล่าวว่า: ฉันจะหลีกเลี่ยงตัวแปรทั่วโลกถ้าคุณสามารถทำได้ (และคุณเกือบจะทำได้) ดังที่ฉันได้กล่าวไปแล้วพวกเขากลายเป็นคุณสมบัติของwindowและwindowมีผู้คนจำนวนมากพอที่องค์ประกอบทั้งหมดที่มีid(และอีกมากมายที่มีเพียงname) ถูกทิ้งไว้ในนั้น (และไม่ว่าข้อมูลจำเพาะที่จะเกิดขึ้นnameนั้น )

ให้ล้อมรอบโค้ดของคุณในฟังก์ชันการกำหนดขอบเขตและใช้ตัวแปรท้องถิ่นกับฟังก์ชันการกำหนดขอบเขตนั้นและทำให้ฟังก์ชันอื่น ๆ ของคุณปิดภายใน:

<script>
(function() { // Begin scoping function
    var yourGlobalVariable; // Global to your code, invisible outside the scoping function
    function foo() {
        // ...
    }
})();         // End scoping function
</script>

98
+1 การประกาศอย่างชัดเจนไปที่หน้าต่างเป็นวิธีที่อ่านง่ายที่สุด
Caspar Kleijne

8
โปรดทราบว่าการใช้windowจะไม่ทำงานในโหนด เคล็ดลับที่ง่ายที่สุดที่นี่คือการตั้ง: GLOBAL.window = GLOBAL;- ตามที่อธิบายไว้ในคำถามที่เกี่ยวข้องนี้ แน่นอนว่ามันไม่ใช่แนวคิดที่ค่อนข้างสวย ฉันชอบที่จะทำในสิ่งที่ทางรอบอื่น ๆ เพื่อให้สามารถใช้แทนGLOBAL window
Domi

4
@ CasparKleijne ฉันไม่เข้าใจ ทำไมคุณต้องกำหนดบนหน้าต่างเมื่อคุณไม่มีหลักฐานว่าวัตถุหน้าต่างมีอยู่จริง คุณไม่รู้อะไรเกี่ยวกับวิธีการใช้รหัสของคุณในอนาคต มันอาจถูกใช้ในสภาพแวดล้อม MongoDB หรือ rino แทนโหนดของคุณ และวัตถุหน้าต่างยังมองไม่เห็นแม้ในเบราว์เซอร์ถ้าคุณใช้งานเว็บเช่น นี่จะฆ่าการใช้ซ้ำได้อย่างสมบูรณ์
Gherman

4
window.yourGlobalVariable = ...;ทำงานได้อย่างมีเสน่ห์หลังจากอ่านคำถาม 5 ถึง 6 ข้อในไซต์สแต็ก
Ahmed Syed

6
@JacquesKoekemoer: ไม่มีเหตุผลอะไรที่จะใช้evalมัน แทน:window[dynamic_variable_name] = dynamic_variable_value;
TJ Crowder

19

UPDATE1: ถ้าคุณอ่านความคิดเห็นมีการสนทนาที่ดีเกี่ยวกับการตั้งชื่อเฉพาะนี้

UPDATE2: ดูเหมือนว่าเนื่องจากคำตอบของฉันถูกโพสต์ในอนุสัญญาการตั้งชื่อแล้ว ผู้ที่สอนเขียนหนังสือ ฯลฯ พูดเกี่ยวกับvarคำประกาศและfunctionคำประกาศ

UPDATE3: นี่คือโพสต์ wikipedia เพิ่มเติมที่สนับสนุนประเด็นของฉัน: http://en.wikipedia.org/wiki/Declaration_(computer_programming)#Declarations_and_Definitions

... และเพื่อตอบคำถามหลัก ประกาศตัวแปรก่อนฟังก์ชันของคุณ สิ่งนี้จะได้ผลและจะเป็นไปตามแนวปฏิบัติที่ดีในการประกาศตัวแปรของคุณที่ด้านบนสุดของขอบเขต :)


7
หากคุณต้องการกำหนดตัวแปรของคุณที่อื่นให้แน่ใจว่าเข้าใจว่าการยกคืออะไร นี่เป็นบทความที่ดีมากเกี่ยวกับเรื่องนี้adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting โชคดี!
op1ekun

1
นี่ไม่ใช่สิ่งที่definitionและdeclarationหมายถึงใน C. บรรทัดแรกของคุณอาจเป็นการประกาศหรือคำจำกัดความ (ขึ้นอยู่กับว่ามันอยู่ที่ไหน) ที่สองเป็นเพียงการมอบหมาย การประกาศเพียงระบุการตีความของตัวระบุ (เช่น. myVaris int) ถ้าประกาศยังdefinitionขอสงวนการจัดเก็บก็เป็น สิ่งนี้ไม่เกี่ยวข้องกับการพิมพ์; เป็นส่วนหนึ่งของวิธีที่หน่วยการรวบรวมเข้าใจการอ้างอิงถึงหน่วยการรวบรวมอื่น ๆ
EML

4
แม้จะอยู่ใน JS, var myVarเรียกว่าประกาศ (มันไม่จำเป็นต้องพิมพ์) และที่ได้รับมอบหมาย ฉันเคยได้ยินคำว่า "defintion" สำหรับสารประกอบ ( ) myVar = 10var myVar = 10;
Bergi

2
สิ่งนี้ไม่ได้ช่วยตอบคำถาม มันควรจะเป็นความคิดเห็นไม่ใช่คำตอบ
Stuntddude

2
@Stuntddude คุณอาจจะถูก :( ฉันเริ่มตอบคำถามแล้วตัดสินใจแยกออกเล็กน้อยและนี่คือสิ่งที่เรามียัง ppl บางคนยังพบว่ามีประโยชน์ดังนั้นฉันจึงทิ้งมันไว้ที่นี่ขอบคุณสำหรับคุณ ข้อเสนอแนะ!
op1ekun

15

เพียงแค่ประกาศ

var trialImage;

ด้านนอก แล้วก็

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

หวังว่านี่จะช่วยได้


12

ไม่คุณไม่สามารถ เพียงประกาศตัวแปรที่อยู่นอกฟังก์ชั่น คุณไม่ต้องประกาศในเวลาเดียวกับที่คุณกำหนดค่า:

var trailimage;

function makeObj(address) {
  trailimage = [address, 50, 50];

1
ขออภัย! "เป็นไปได้ไหมที่จะกำหนดตัวแปรกลางในฟังก์ชัน JavaScript?" - "ไม่คุณทำไม่ได้" ไม่ถูกต้องเนื่องจากคำตอบแรกแสดง!
mustafa.0x

5
@ mustafa.0x: คุณเข้าใจผิด คุณไม่สามารถกำหนดตัวแปรโกลบอลภายในฟังก์ชัน คุณสามารถสร้างตัวแปรโกลบอลได้หรือสร้างคุณสมบัติหน้าต่างภายในฟังก์ชัน แต่คุณไม่สามารถกำหนดตัวแปรโกลบอลภายในฟังก์ชันได้
Guffa

1
เกี่ยวกับ JavaScript ในสภาพแวดล้อมของเบราว์เซอร์ตัวแปรทั่วโลกและคุณสมบัติของwindowคำพ้องความหมาย ไม่ว่าจะด้วยวิธีใดความแตกต่างทางความหมายที่คุณทำนั้นชัดเจนดังนั้นฉันจึงไม่รังเกียจที่จะไม่ลงมือ แก้ไข: ไม่สามารถเปลี่ยนการลงคะแนนของฉันขอโทษ!
mustafa.0x

2
หากคุณไม่ได้ใช้แบบเข้มงวด (แต่ทำไมคุณไม่ใช้แบบเข้มงวด) คุณสามารถ ประกาศและกำหนดค่า vars สากลภายในฟังก์ชันโดยขัดกับแนวปฏิบัติที่ดีทั้งหมดและไม่ได้ใช้varซึ่งเป็นความหมายของ Guffa ที่สร้างขึ้นโดยปริยาย (เช่น @DhruvPathak ชี้ไปที่นั่นด้วย)
cregox

11

เพียงประกาศนอกฟังก์ชั่นและกำหนดค่าภายในฟังก์ชั่น สิ่งที่ต้องการ:

<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);

3

มันง่ายมากที่กำหนดตัวแปร trailimage นอกฟังก์ชั่นและตั้งค่าในฟังก์ชั่น makeObj ตอนนี้คุณสามารถเข้าถึงคุณค่าได้จากทุกที่

var offsetfrommouse = [10, -20];
var displayduration = 0;
var obj_selected = 0;
var trailimage;
function makeObj(address) {
      trailimage = [address, 50, 50];
      ....
}

2
    var Global = 'Global';

    function LocalToGlobalVariable() {

    //This creates a local variable.

    var Local = '5';

    //Doing this makes the variable available for one session
    //(a page refresh - Its the session not local)

    sessionStorage.LocalToGlobalVar = Local;

    // It can be named anything as long as the sessionStorage references the local variable.
    // Otherwise it won't work
    //This refreshes the page to make the variable take effect instead of the last variable set.

    location.reload(false);
    };

    //This calls the variable outside of the function for whatever use you want.

    sessionStorage.LocalToGlobalVar;

ฉันรู้ว่าอาจมีข้อผิดพลาดทางไวยากรณ์มากมายในเรื่องนี้ แต่เป็นความคิดทั่วไป ... ขอบคุณ LayZee มากที่ชี้เรื่องนี้ ... คุณสามารถค้นหาว่า Local และ Session Storage นั้นอยู่ที่http: //www.w3schools ดอทคอม ฉันต้องการสิ่งเดียวกันสำหรับรหัสของฉันและนี่เป็นความคิดที่ดีจริงๆ


ถึงตอนนี้เป็นคำตอบเดียวที่ใช้งานได้ แต่ต้องโหลดหน้าซ้ำและlocation.reload(false);รีเฟรชหน้าซ้ำ ๆ
iyrin

1

ตัวอย่างคลาสสิก:

window.foo = 'bar';

ตัวอย่างที่ทันสมัยและปลอดภัยปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดโดยใช้IIFE :

;(function (root) {
    'use strict'

    root.foo = 'bar';
)(this));

ปัจจุบันยังมีตัวเลือกในการใช้WebStorage API

localStorage.foo = 42;

หรือ

sessionStorage.bar = 21;

ตามประสิทธิภาพฉันไม่แน่ใจว่ามันช้ากว่าการเก็บค่าในตัวแปรหรือไม่

การสนับสนุนเบราว์เซอร์อย่างกว้างขวางตามที่ระบุไว้บนฉันสามารถใช้ ...


localStorage และ sessionStorage ใช้งานได้เฉพาะกับค่าสตริง
HereToLearn_

นั่นเป็นสิทธิ @HereToLearn_ แต่แล้วคุณสามารถใช้และlocalStorage.foo = JSON.stringify({ arbitrary: 'object', meaning: 42, awesome: true }); var foo = JSON.decode(localStorage.foo);
Lars Gyrup Brink Nielsen

สิ่งที่localStorageจะทำอย่างไรกับตัวแปรทั่วโลกหรือไม่
MichałPerłakowski

1
OP กำลังหาทางแก้ไขปัญหานี้: "ฉันต้องการใช้ตัวแปร trailimage (ประกาศในฟังก์ชั่น makeObj) ในฟังก์ชั่นอื่น ๆ " ใครบอกว่าวิธีแก้ปัญหาต้องเกี่ยวข้องกับตัวแปรทั่วโลก ตัวแปรทั่วโลกเป็นสิ่งที่ดีสำหรับทุกสิ่ง
Lars Gyrup Brink Nielsen

0

คุณต้องการให้ตัวแปรภายในฟังก์ชั่นใช้งานนอกฟังก์ชั่นหรือไม่? ทำไมไม่ส่งคืนผลลัพธ์ของตัวแปรภายในฟังก์ชั่น? var x = function returnX { var x = 0; return x; }เป็นความคิด ...

    <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;
            return trailimage;
        }

        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>

ฉันยังไม่ได้ทดสอบสิ่งนี้ แต่ถ้ารหัสของคุณทำงานก่อนที่จะมีการเปลี่ยนแปลงเล็กน้อยมันก็น่าจะใช้ได้


-1

นี่คือตัวอย่างโค้ดที่อาจช่วยได้

  var Human = function(){
   name = "Shohanur Rahaman";  // global variable
   this.name = "Tuly"; // constructor variable 
   var age = 21;
 };

  var shohan = new Human();

 document.write(shohan.name+"<br>");
 document.write(name);
 document.write(age); // undefined cause its local variable 

ที่นี่ฉันพบคำตอบที่ดีวิธีการประกาศตัวแปรทั่วโลกใน JavaScript


ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
Rohit Gupta

-1

นี่เป็นอีกวิธีที่ง่ายในการทำให้ตัวแปรพร้อมใช้งานในฟังก์ชั่นอื่น ๆ โดยไม่ต้องใช้ตัวแปรโกลบอล:

function makeObj() {
  // var trailimage = 'test';
  makeObj.trailimage = 'test';
}
function someOtherFunction() {
  document.write(makeObj.trailimage);
}

makeObj();
someOtherFunction();


-2

หากคุณกำลังสร้างฟังก์ชั่นเริ่มต้นคุณสามารถกำหนดฟังก์ชั่นทั่วโลกและตัวแปรในลักษณะดังกล่าว:

function(globalScope)
{
     //define something
     globalScope.something() { 
         alert("It works");
     };
}(window)

เนื่องจากฟังก์ชันถูกเรียกใช้ทั่วโลกพร้อมกับอาร์กิวเมนต์นี้นี่คือขอบเขตส่วนกลางที่นี่ ดังนั้นสิ่งที่ควรเป็นสิ่งที่ทั่วโลก


thisอยู่undefinedในโหมดเข้มงวดนอกฟังก์ชั่นและไม่ควรใช้เพื่ออ้างถึงวัตถุระดับโลก
MichałPerłakowski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.