วิธีการประกาศตัวแปรส่วนกลางในไฟล์. js


87

ฉันต้องการตัวแปรส่วนกลางสองสามตัวที่ฉันต้องการใน.jsไฟล์ทั้งหมด

ตัวอย่างเช่นพิจารณา 4 ไฟล์ต่อไปนี้:

  1. global.js
  2. js1.js
  3. js2.js
  4. js3.js

มีวิธีใดบ้างที่ฉันสามารถประกาศตัวแปรส่วนกลาง 3 ตัวในglobal.jsและเข้าถึงตัวแปรเหล่านั้นในอีก 3 .jsไฟล์โดยพิจารณาว่าฉันโหลด 4 ไฟล์ข้างต้นทั้งหมดลงในเอกสาร HTML

ใครช่วยบอกฉันหน่อยได้ไหมว่าเป็นไปได้หรือมีวิธีแก้ไขเพื่อให้บรรลุสิ่งนี้?

คำตอบ:


97

เพียงกำหนดตัวแปรของคุณใน global.js นอกขอบเขตฟังก์ชัน:

// global.js
var global1 = "I'm a global!";
var global2 = "So am I!";

// other js-file
function testGlobal () {
    alert(global1);
}

เพื่อให้แน่ใจว่าได้ผลคุณต้องรวม / ลิงก์ไปที่ global.js ก่อนที่คุณจะพยายามเข้าถึงตัวแปรใด ๆ ที่กำหนดไว้ในไฟล์นั้น:

<html>
    <head>
        <!-- Include global.js first -->
        <script src="/YOUR_PATH/global.js" type="text/javascript"></script>
        <!-- Now we can reference variables, objects, functions etc. 
             defined in global.js -->
        <script src="/YOUR_PATH/otherJsFile.js" type="text/javascript"></script>
    </head>
    [...]
</html>

แน่นอนคุณสามารถเชื่อมโยงในแท็กสคริปต์ก่อนแท็กปิด <body> หากคุณไม่ต้องการให้การโหลดไฟล์ js ขัดขวางการโหลดหน้าเริ่มต้น


4
แม้ว่าคำตอบนี้จะถูกต้องฉันขอแนะนำให้คุณกำหนดขอบเขตตัวแปร Javascript ของ Google เพื่อความเข้าใจที่ดีขึ้นและอาจหลีกเลี่ยงการทำสิ่งต่างๆในลักษณะนี้
aleemb

1
ตกลง ฉันพยายามกำหนดขอบเขตฟังก์ชันและตัวแปรทั้งหมดใน "เนมสเปซ" ทั่วไปเสมอเพื่อหลีกเลี่ยงความยุ่งเหยิงและความขัดแย้ง โดยปกติฉันจะตั้งชื่อเป็นตัวย่อของโครงการหรือ บริษัท
PatrikAkerstrand

การลงคะแนนคำตอบนี้และคนอื่น ๆ ชอบเพราะถือว่าตัวแปร global จะถูกสร้างขึ้นในขอบเขตส่วนกลางและยังกำหนดให้การกล่าวถึงตัวแปรเป็นครั้งแรกอยู่ในขอบเขตส่วนกลางก่อนที่จะกล่าวถึงอื่น ๆ ทั้งหมด
Andrew

1
@ แอนดรูว์คำตอบนี้เขียนเมื่อแปดปีที่แล้ว สำหรับเจตนาและวัตถุประสงค์ทั้งหมดมันถูกต้องในตอนนั้น หากคุณต้องการมีส่วนร่วมจริงๆคุณอาจต้องการแนะนำให้แก้ไขแทน?
PatrikAkerstrand

@PatrikAkerstrand การออกเดทไม่ได้สร้างความแตกต่าง คำตอบอื่น ๆ ที่ใช้ global object ก็เพียงพอแล้ว ฉันอธิบายว่าเหตุใดจึงไม่เป็นเช่นนั้น
แอนดรูว์

90

แนวทางที่แนะนำคือ:

window.greeting = "Hello World!"

จากนั้นคุณสามารถเข้าถึงได้ภายในฟังก์ชันใด ๆ :

function foo() {

   alert(greeting); // Hello World!
   alert(window["greeting"]); // Hello World!
   alert(window.greeting); // Hello World! (recommended)

}

แนวทางนี้เป็นที่ต้องการด้วยเหตุผลสองประการ

  1. มีเจตนาชัดเจน การใช้varคำหลักสามารถนำไปสู่การประกาศทั่วโลกvarsที่ตั้งใจให้เป็นแบบท้องถิ่นหรือในทางกลับกัน การกำหนดขอบเขตตัวแปรประเภทนี้เป็นจุดที่สร้างความสับสนให้กับนักพัฒนา Javascript จำนวนมาก ดังนั้นเป็นกฎทั่วไปผมให้แน่ใจว่าการประกาศตัวแปรทั้งหมดจะนำหน้าด้วยคำหลักหรือคำนำหน้าvarwindow

  2. คุณสร้างมาตรฐานของไวยากรณ์นี้สำหรับการอ่านตัวแปรด้วยวิธีนี้เช่นกันซึ่งหมายความว่าขอบเขตในเครื่องvarจะไม่บดบังทั่วโลกvarหรือในทางกลับกัน ตัวอย่างเช่นสิ่งที่เกิดขึ้นที่นี่ไม่ชัดเจน:

 

 greeting = "Aloha";

 function foo() {
     greeting = "Hello"; // overrides global!
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // does it alert "Hello" or "Howdy" ?

อย่างไรก็ตามสิ่งนี้สะอาดกว่ามากและมีข้อผิดพลาดน้อยกว่า (คุณไม่จำเป็นต้องจำกฎการกำหนดขอบเขตตัวแปรทั้งหมด):

 function foo() {
     window.greeting = "Hello";
 }

 function bar(greeting) {
   alert(greeting);
 }

 foo();
 bar("Howdy"); // alerts "Howdy"

การแนบตัวแปรเข้ากับหน้าต่างควรใช้ได้กับทุกเบราว์เซอร์ (และเป็นวิธีที่ฉันใช้ +1!)
Dandy

1
@ แดนถ้าคุณประกาศว่า "var testvar = 'hello';" นอกฟังก์ชั่นมันจะถูกเพิ่มลงในวัตถุหน้าต่างโดยอัตโนมัติและคุณสามารถเข้าถึงได้ด้วย "window.testvar"
zkent

1
@zkent ถูกต้อง แต่การใช้ Window object ก็ยังดีกว่าเพราะคุณอาจต้องการเปลี่ยนรหัสของคุณให้เป็น sth เหมือนกาแฟในภายหลัง
Nami WANG

ใช้ Window แทนคำนำหน้าเอกสารดีกว่าไหม
Andrew

7

คุณลองหรือยัง?

ถ้าคุณทำ:

var HI = 'Hello World';

ในglobal.js. แล้วทำ:

alert(HI);

ในjs1.jsนั้นจะแจ้งเตือนได้ดี คุณต้องรวมไว้global.jsก่อนส่วนที่เหลือในเอกสาร HTML

สิ่งเดียวที่จับได้คือคุณต้องประกาศในขอบเขตของหน้าต่าง (ไม่ใช่ในฟังก์ชันใด ๆ )

คุณสามารถแยกvarส่วนและสร้างมันขึ้นมาได้ แต่มันไม่ใช่แนวปฏิบัติที่ดี


7

ตามที่กล่าวไว้ข้างต้นมีปัญหาในการใช้ขอบเขตสูงสุดในไฟล์สคริปต์ของคุณ นี่คือปัญหาอื่น: ไฟล์สคริปต์อาจถูกเรียกใช้จากบริบทที่ไม่ใช่บริบทส่วนกลางในสภาพแวดล้อมรันไทม์บางอย่าง

มีการเสนอให้มอบหมายให้ทั่วโลกwindowโดยตรง แต่นั่นขึ้นอยู่กับเวลาทำงานและไม่ทำงานในโหนดเป็นต้นแสดงให้เห็นว่าการจัดการตัวแปรส่วนกลางแบบพกพาจำเป็นต้องมีการพิจารณาอย่างรอบคอบและใช้ความพยายามเป็นพิเศษ บางทีพวกเขาอาจจะแก้ไขได้ในเวอร์ชัน ECMS ในอนาคต!

สำหรับตอนนี้ฉันขอแนะนำสิ่งนี้เพื่อสนับสนุนการจัดการทั่วโลกที่เหมาะสมสำหรับสภาพแวดล้อมรันไทม์ทั้งหมด:

/**
 * Exports the given object into the global context.
 */
var exportGlobal = function(name, object) {
    if (typeof(global) !== "undefined")  {
        // Node.js
        global[name] = object;
    }
    else if (typeof(window) !== "undefined") {
        // JS with GUI (usually browser)
        window[name] = object;
    }
    else {
        throw new Error("Unkown run-time environment. Currently only browsers and Node.js are supported.");
    }
};


// export exportGlobal itself
exportGlobal("exportGlobal", exportGlobal);

// create a new global namespace
exportGlobal("someothernamespace", {});

เป็นการพิมพ์ที่มากขึ้นเล็กน้อย แต่ทำให้การจัดการตัวแปรทั่วโลกของคุณเป็นหลักฐานในอนาคต

Disclaimer: ส่วนหนึ่งของความคิดนี้มาให้ฉันเมื่อมองไปที่รุ่นก่อนหน้าของstacktrace.js

ฉันคิดว่าเราสามารถใช้ Webpack หรือเครื่องมืออื่น ๆ เพื่อให้ตรวจจับสภาพแวดล้อมรันไทม์ได้อย่างน่าเชื่อถือและน้อยลง


2
GLOBALตอนนี้เลิกใช้งานแล้วและglobalควรใช้แทน
โธมัส

2

ใช่คุณสามารถเข้าถึงได้ คุณควรประกาศใน 'พื้นที่สาธารณะ' (นอกฟังก์ชันใด ๆ ) เป็น:

var globalvar1 = 'value';

คุณสามารถเข้าถึงได้ในภายหลังและในไฟล์อื่น ๆ

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