วัตถุประสงค์ของการห่อไฟล์ Javascript ทั้งหมดในฟังก์ชั่นที่ไม่ระบุชื่อเช่น“ (function () {…}) ()” คืออะไร?


584

ฉันได้อ่านจาวาสคริปต์จำนวนมากเมื่อเร็ว ๆ นี้และฉันได้สังเกตเห็นว่าไฟล์ทั้งหมดถูกห่อเหมือนไฟล์ต่อไปนี้ในไฟล์. js ที่จะนำเข้า

(function() {
    ... 
    code
    ...
})();

อะไรคือเหตุผลในการทำสิ่งนี้มากกว่าฟังก์ชั่นคอนสตรัคเตอร์ที่เรียบง่าย?


6
เนื่องจากฉันคิดว่าคนจำนวนมากจะถูกใช้งานนี้โปรดอย่าลืมการปิดบัญชี
dgh

5
เทคนิคนี้เรียกว่า "IIFE" ฉันคิดว่า สิ่งนี้ย่อมาจาก Function Expression ที่ถูกเรียกใช้ในทันทีen.wikipedia.org/wiki/Immediately-invoked_function_expression
Adrien เป็น

คำตอบ:


786

โดยปกติจะเป็นเนมสเปซ (ดูในภายหลัง) และควบคุมการแสดงผลของฟังก์ชันสมาชิกและ / หรือตัวแปร คิดว่ามันเหมือนคำนิยามของวัตถุ ชื่อทางเทคนิคของมันคือนิพจน์ฟังก์ชันที่เรียกใช้ทันที (IIFE) ปลั๊กอิน jQuery มักเขียนเช่นนี้

ใน Javascript คุณสามารถซ้อนฟังก์ชันได้ ดังนั้นสิ่งต่อไปนี้ถูกต้องตามกฎหมาย:

function outerFunction() {
   function innerFunction() {
      // code
   }
}

ตอนนี้คุณสามารถโทรหาouterFunction()แต่การแสดงของinnerFunction()จะถูก จำกัด ขอบเขตของความหมายมันคือส่วนตัวถึงouterFunction() outerFunction()มันเป็นไปตามหลักการเดียวกันกับตัวแปรใน Javascript:

var globalVariable;

function someFunction() {
   var localVariable;
}

ที่สอดคล้องกัน:

function globalFunction() {

   var localFunction1 = function() {
       //I'm anonymous! But localFunction1 is a reference to me!
   };

   function localFunction2() {
      //I'm named!
   }
}

ในสถานการณ์ดังกล่าวข้างต้นคุณสามารถโทรglobalFunction()ได้จากทุกที่ แต่คุณไม่สามารถเรียกหรือlocalFunction1localFunction2

สิ่งที่คุณทำเมื่อคุณเขียน(function() { ... })()คือคุณกำลังสร้างโค้ดภายในวงเล็บชุดแรกเป็นตัวอักษรฟังก์ชั่น (หมายถึง "วัตถุทั้งหมด" เป็นจริงฟังก์ชัน) หลังจากนั้นคุณจะเรียกใช้ฟังก์ชัน (ตัวสุดท้าย()) ที่คุณเพิ่งกำหนดเอง ดังนั้นข้อได้เปรียบที่สำคัญของสิ่งนี้ตามที่ฉันได้กล่าวไว้ก่อนหน้าคือคุณสามารถมีวิธี / ฟังก์ชันและคุณสมบัติส่วนตัว:

(function() {
   var private_var;

   function private_function() {
     //code
   }
})();

ในตัวอย่างแรกคุณจะต้องเรียกใช้globalFunctionชื่ออย่างชัดเจนเพื่อเรียกใช้ นั่นคือคุณจะทำglobalFunction()เพื่อเรียกใช้ แต่ในตัวอย่างข้างต้นคุณไม่เพียงแค่นิยามฟังก์ชัน คุณกำลังกำหนดและเรียกมันในครั้งเดียว ซึ่งหมายความว่าเมื่อโหลดไฟล์ JavaScript ของคุณแล้วจะมีการเรียกใช้งานทันที แน่นอนคุณสามารถทำได้:

function globalFunction() {
    // code
}
globalFunction();

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

สิ่งที่ประณีตด้วย IIFEs คือคุณสามารถกำหนดสิ่งต่าง ๆ ภายในและเปิดเผยเฉพาะส่วนที่คุณต้องการกับโลกภายนอกดังนั้น (ตัวอย่างของการตั้งชื่อเพื่อให้คุณสามารถสร้างไลบรารี่ / ปลั๊กอินของคุณเอง):

var myPlugin = (function() {
 var private_var;

 function private_function() {
 }

 return {
    public_function1: function() {
    },
    public_function2: function() {
    }
 }
})()

ตอนนี้คุณสามารถโทรmyPlugin.public_function1()แต่คุณไม่สามารถเข้าถึงได้private_function()! ค่อนข้างคล้ายกับนิยามของคลาส เพื่อความเข้าใจที่ดีขึ้นนี้ฉันขอแนะนำลิงก์ต่อไปนี้สำหรับการอ่านเพิ่มเติม:

แก้ไข

ฉันลืมที่จะพูดถึง ในขั้นตอนสุดท้าย()คุณสามารถผ่านสิ่งที่คุณต้องการภายใน ตัวอย่างเช่นเมื่อคุณสร้างปลั๊กอิน jQuery คุณจะผ่านjQueryหรือ$ชอบ:

(function(jQ) { ... code ... })(jQuery) 

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

  • คุณสามารถกำหนดพารามิเตอร์ส่วนกลางอีกครั้งและตั้งชื่อที่เหมาะสมในขอบเขตท้องถิ่น
  • มีข้อได้เปรียบด้านประสิทธิภาพเล็กน้อยเนื่องจากเร็วกว่าที่จะค้นหาสิ่งต่าง ๆ ในขอบเขตของท้องถิ่นแทนที่จะต้องเดินตามสายขอบเขตเข้าไปในขอบเขตส่วนกลาง
  • มีประโยชน์สำหรับการบีบอัด (การลดขนาด)

ก่อนหน้านี้ฉันอธิบายว่าฟังก์ชั่นเหล่านี้ทำงานโดยอัตโนมัติอย่างไรเมื่อเริ่มต้น แต่ถ้ามันทำงานโดยอัตโนมัติใครจะผ่านการโต้แย้ง เทคนิคนี้อนุมานว่าพารามิเตอร์ทั้งหมดที่คุณต้องการมีการกำหนดไว้แล้วว่าเป็นตัวแปรทั่วโลก ดังนั้นหาก jQuery ไม่ได้ถูกนิยามเป็นตัวแปรโกลบอลตัวอย่างนี้จะไม่ทำงาน ดังที่คุณอาจคาดเดาได้สิ่งหนึ่งที่ jquery.js ทำในระหว่างการเริ่มต้นคือการกำหนดตัวแปรทั่วโลก 'jQuery' รวมถึงตัวแปรทั่วโลกที่มีชื่อเสียง '$' ซึ่งอนุญาตให้โค้ดนี้ทำงานหลังจากรวม jQuery แล้ว


14
เจ๋งมากฉันเข้าใจเนมสเปซเป็นอย่างดี แต่ฉันเห็นตัวอย่างสุดท้ายของคุณมากมายและไม่สามารถเข้าใจได้ว่าผู้คนกำลังพยายามทำให้สำเร็จ สิ่งนี้จะช่วยล้างสิ่งต่างๆ
Andrew Kou

34
โพสต์ที่น่ากลัว ขอบคุณมาก.
Darren

4
ฉันคิดว่าการเพิ่มเซมิโคลอนนำหน้าและต่อท้าย ';' จะทำให้ตัวอย่างสมบูรณ์ - ;(function(jQ) { ... code ... })(jQuery);ด้วยวิธีนี้ถ้ามีคนทิ้งเซมิโคลอนไว้ในสคริปต์ของพวกเขามันจะไม่ทำให้คุณเสียโดยเฉพาะอย่างยิ่งถ้าคุณวางแผนที่จะย่อขนาดและต่อสคริปต์ของคุณกับผู้อื่น
Taras Alenin

3
โพสต์ที่ดีฉันชอบเน้นตัวแปรส่วนตัว ฉันยังชอบการเปิดในรูปแบบโมดูล / การปิด (public_function1 & public_function2) & วิธีที่คุณส่งผ่านตัวแปรแม้ว่าการออกนอกขอบเขตเล็กน้อยมันเป็นการแนะนำที่ดี ฉันยังเพิ่มคำตอบหนึ่งนี้เพ่งความสนใจไปที่สิ่งที่ฉันคิดว่าเป็นรากของไวยากรณ์และความแตกต่างระหว่างคำสั่งฟังก์ชั่นการแสดงออกของฟังก์ชั่นและสิ่งที่ฉันคิดว่าเป็น "เพียงแค่การประชุม" vs "วิธีเดียวที่จะบรรลุผลนี้"
Adrien เป็น

4
โพสต์ยอดเยี่ยมฉันคิดว่าอาจเพิ่มเติมเกี่ยวกับวิธีการส่งผ่านตัวแปรไปยังฟังก์ชันการดำเนินการด้วยตนเองนั้นมีประโยชน์ บริบทในฟังก์ชั่นการดำเนินการด้วยตนเองนั้นสะอาดไม่มีข้อมูล คุณสามารถส่งผ่านบริบทโดยการทำสิ่งนี้(function (context) { ..... })(this)ซึ่งจะช่วยให้คุณสามารถแนบสิ่งที่คุณต้องการกับบริบทหลักดังนั้นจึงเผยให้เห็น
Callum Linington

79

ในระยะสั้น

สรุป

ในรูปแบบที่ง่ายที่สุดเทคนิคนี้มีจุดมุ่งหมายที่จะตัดรหัสภายในขอบเขตฟังก์ชั่น

ช่วยลดโอกาสในการ:

  • การปะทะกับแอปพลิเคชั่น / ไลบรารีอื่น ๆ
  • ก่อให้เกิดมลพิษที่เหนือกว่า (มีแนวโน้มมากที่สุดในโลก)

มันไม่ตรวจจับเมื่อเอกสารพร้อม - ไม่ใช่document.onloadหรือwindow.onload

มันเป็นที่รู้จักกันทั่วไปว่าเป็นหรือImmediately Invoked Function Expression (IIFE)Self Executing Anonymous Function

รหัสอธิบาย

var someFunction = function(){ console.log('wagwan!'); };

(function() {                   /* function scope starts here */
  console.log('start of IIFE');

  var myNumber = 4;             /* number variable declaration */
  var myFunction = function(){  /* function variable declaration */
    console.log('formidable!'); 
  };
  var myObject = {              /* object variable declaration */
    anotherNumber : 1001, 
    anotherFunc : function(){ console.log('formidable!'); }
  };
  console.log('end of IIFE');
})();                           /* function scope ends */

someFunction();            // reachable, hence works: see in the console
myFunction();              // unreachable, will throw an error, see in the console
myObject.anotherFunc();    // unreachable, will throw an error, see in the console

ในตัวอย่างข้างต้นตัวแปรใด ๆ ที่กำหนดไว้ในฟังก์ชั่น (เช่นประกาศโดยใช้var) จะเป็น "ส่วนตัว" และสามารถเข้าถึงได้ภายในขอบเขตฟังก์ชั่นเท่านั้น (ตามที่ Vivin Paliath ใส่ไว้) กล่าวอีกนัยหนึ่งตัวแปรเหล่านี้ไม่สามารถมองเห็น / เข้าถึงได้นอกฟังก์ชั่น ดูการสาธิตสด

Javascript มีฟังก์ชันกำหนดขอบเขต "พารามิเตอร์และตัวแปรที่กำหนดในฟังก์ชั่นไม่สามารถมองเห็นได้นอกฟังก์ชั่นและตัวแปรที่กำหนดไว้ที่ใดก็ได้ภายในฟังก์ชั่นสามารถมองเห็นได้ทุกที่ภายในฟังก์ชัน" (จาก "Javascript: The Good Parts")


รายละเอียดเพิ่มเติม

รหัสทางเลือก

ในท้ายที่สุดโค้ดที่โพสต์ก่อนหน้าสามารถทำได้ดังนี้:

var someFunction = function(){ console.log('wagwan!'); };

var myMainFunction = function() {
  console.log('start of IIFE');

  var myNumber = 4;
  var myFunction = function(){ console.log('formidable!'); };
  var myObject = { 
    anotherNumber : 1001, 
    anotherFunc : function(){ console.log('formidable!'); }
  };
  console.log('end of IIFE');
};

myMainFunction();          // I CALL "myMainFunction" FUNCTION HERE
someFunction();            // reachable, hence works: see in the console
myFunction();              // unreachable, will throw an error, see in the console
myObject.anotherFunc();    // unreachable, will throw an error, see in the console

ดูการสาธิตสด


ราก

การวนซ้ำ 1

อยู่มาวันหนึ่งบางคนอาจคิดว่า "ต้องมีวิธีที่จะหลีกเลี่ยงการตั้งชื่อ 'myMainFunction' เนื่องจากสิ่งที่เราต้องการคือการดำเนินการทันที

หากคุณกลับไปสู่พื้นฐานคุณจะพบว่า:

  • expression: สิ่งที่ประเมินค่า กล่าวคือ3+11/x
  • statement: บรรทัดของโค้ดที่ทำอะไรบางอย่าง แต่มันไม่ได้ประเมินค่า กล่าวคือif(){}

ในทำนองเดียวกันฟังก์ชั่นการแสดงออกประเมินเป็นค่า และสิ่งหนึ่งที่เป็นผล (ฉันสมมติว่า?) คือพวกเขาสามารถเรียกใช้ได้ทันที:

 var italianSayinSomething = function(){ console.log('mamamia!'); }();

ดังนั้นตัวอย่างที่ซับซ้อนมากขึ้นของเราจะกลายเป็น:

var someFunction = function(){ console.log('wagwan!'); };

var myMainFunction = function() {
  console.log('start of IIFE');

  var myNumber = 4;
  var myFunction = function(){ console.log('formidable!'); };
  var myObject = { 
    anotherNumber : 1001, 
    anotherFunc : function(){ console.log('formidable!'); }
  };
  console.log('end of IIFE');
}();

someFunction();            // reachable, hence works: see in the console
myFunction();              // unreachable, will throw an error, see in the console
myObject.anotherFunc();    // unreachable, will throw an error, see in the console

ดูการสาธิตสด

การวนซ้ำ 2

ขั้นตอนต่อไปคือความคิด "ทำไมมีvar myMainFunction =ถ้าเราไม่แม้แต่ใช้มัน!"

คำตอบนั้นง่าย: ลองลบออกเช่นด้านล่าง:

 function(){ console.log('mamamia!'); }();

ดูการสาธิตสด

มันจะไม่ทำงานเพราะ"การประกาศฟังก์ชั่นไม่ได้ invokable"

เคล็ดลับคือว่าโดยการเอาvar myMainFunction =เราเปลี่ยนการแสดงออกของฟังก์ชั่นเป็นประกาศฟังก์ชัน ดูลิงค์ใน "ทรัพยากร" สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้

คำถามต่อไปคือ "ทำไมฉันไม่สามารถเก็บมันไว้เป็นนิพจน์ฟังก์ชั่นกับสิ่งอื่นที่ไม่ใช่var myMainFunction =?

คำตอบคือ "คุณทำได้" และมีหลายวิธีที่คุณสามารถทำได้: การเพิ่ม a +, !a -, หรืออาจจะรวมอยู่ในวงเล็บคู่หนึ่ง ตัวอย่างเช่น

 (function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.

หรือ

 +function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console

หรือ

 -function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console

ดังนั้นเมื่อมีการเพิ่มการแก้ไขที่เกี่ยวข้องกับสิ่งที่ครั้งหนึ่งเคยเป็น "รหัสทางเลือก" ของเราเราจะกลับไปที่รหัสเดียวกันกับที่ใช้ในตัวอย่าง "รหัสอธิบาย"

var someFunction = function(){ console.log('wagwan!'); };

(function() {
  console.log('start of IIFE');

  var myNumber = 4;
  var myFunction = function(){ console.log('formidable!'); };
  var myObject = { 
    anotherNumber : 1001, 
    anotherFunc : function(){ console.log('formidable!'); }
  };
  console.log('end of IIFE');
})();

someFunction();            // reachable, hence works: see in the console
myFunction();              // unreachable, will throw an error, see in the console
myObject.anotherFunc();    // unreachable, will throw an error, see in the console

อ่านเพิ่มเติมเกี่ยวกับExpressions vs Statements:


Demystifying Scopes

สิ่งหนึ่งที่อาจสงสัยคือ "จะเกิดอะไรขึ้นเมื่อคุณไม่นิยามตัวแปร 'อย่างถูกต้อง' ในฟังก์ชั่น - นั่นคือทำการมอบหมายอย่างง่ายแทน?

(function() {
  var myNumber = 4;             /* number variable declaration */
  var myFunction = function(){  /* function variable declaration */
    console.log('formidable!'); 
  };
  var myObject = {              /* object variable declaration */
    anotherNumber : 1001, 
    anotherFunc : function(){ console.log('formidable!'); }
  };
  myOtherFunction = function(){  /* oops, an assignment instead of a declaration */
    console.log('haha. got ya!');
  };
})();
myOtherFunction();         // reachable, hence works: see in the console
window.myOtherFunction();  // works in the browser, myOtherFunction is then in the global scope
myFunction();              // unreachable, will throw an error, see in the console

ดูการสาธิตสด

โดยพื้นฐานแล้วหากตัวแปรที่ไม่ได้ประกาศในขอบเขตปัจจุบันนั้นได้รับการกำหนดค่าดังนั้น "การค้นหาห่วงโซ่ขอบเขตจะเกิดขึ้นจนกว่าจะพบตัวแปรหรือกระทบกับขอบเขตทั่วโลก

เมื่ออยู่ในสภาพแวดล้อมเบราว์เซอร์ (เทียบกับสภาพแวดล้อมเซิร์ฟเวอร์เช่น nodejs) ขอบเขตทั่วโลกจะถูกกำหนดโดยwindowวัตถุ window.myOtherFunction()ดังนั้นเราสามารถทำได้

เคล็ดลับ "แนวทางปฏิบัติที่ดี" ของฉันในหัวข้อนี้คือใช้เสมอvarเมื่อกำหนดสิ่งต่าง ๆ : ไม่ว่าจะเป็นตัวเลขวัตถุหรือฟังก์ชั่น & แม้ในขอบเขตทั่วโลก ทำให้รหัสง่ายขึ้นมาก

บันทึก:

  • จาวาสคริปต์ไม่ได้มีblock scope(ปรับปรุง: บล็อกขอบเขตตัวแปรท้องถิ่นเพิ่มเข้ามาในES6 .)
  • จาวาสคริปต์มีเพียงfunction scope& global scope( windowขอบเขตในสภาพแวดล้อมของเบราว์เซอร์)

อ่านเพิ่มเติมเกี่ยวกับJavascript Scopes:


ทรัพยากร


ขั้นตอนถัดไป

เมื่อคุณได้รับIIFEแนวคิดนี้มันจะนำไปสู่module patternซึ่งมักทำโดยใช้ประโยชน์จากรูปแบบ IIFE นี้ มีความสุข :)


มีประโยชน์มาก ขอบคุณมาก!
Christoffer Helgelin Hald

นีซ, ฉันชอบการสาธิตรุ่น :)
Fabrizio Bertoglio

ช่างเป็นคำอธิบายที่ดีมาก ขอบคุณ!
Vikram Khemlani

26

Javascript ในเบราว์เซอร์มีขอบเขตที่มีประสิทธิภาพเพียงสองอย่างเท่านั้น: ขอบเขตฟังก์ชั่นและขอบเขตทั่วโลก

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


1
แต่ฟังก์ชั่นคอนสตรัคเตอร์ไม่ได้ให้ขอบเขตสำหรับตัวแปรของตัวเองหรือ
Andrew Kou

1
ใช่แต่ละฟังก์ชั่นที่กำหนดไว้ในห้องสมุดนี้สามารถกำหนดตัวแปรท้องถิ่นของตัวเอง แต่สิ่งนี้ช่วยให้ตัวแปรที่ใช้ร่วมกันระหว่างฟังก์ชั่นโดยไม่รั่วไหลออกนอกห้องสมุด
Gareth

@Gareth ดังนั้นสิ่งนี้จะช่วยให้ตัวแปร "ทั่วโลก" อยู่ในขอบเขต (;
Francisco Presencia

2
@FranciscoPresencia "ทั่วโลกภายในขอบเขต" ไม่ใช่วลีที่มีประโยชน์เพราะนั่นเป็นเพียงความหมายของ "ขอบเขต" จุดรวมของขอบเขต "ส่วนกลาง" คือขอบเขตเฉพาะที่ขอบเขตอื่น ๆทั้งหมดสามารถเข้าถึงได้
Gareth

19

ที่เรียกว่าการปิด โดยทั่วไปแล้วมันจะปิดผนึกรหัสภายในฟังก์ชั่นเพื่อให้ห้องสมุดอื่นไม่รบกวนมัน มันคล้ายกับการสร้างเนมสเปซในภาษาที่รวบรวม

ตัวอย่าง. สมมติว่าฉันเขียน:

(function() {

    var x = 2;

    // do stuff with x

})();

ตอนนี้ห้องสมุดอื่น ๆ ไม่สามารถเข้าถึงตัวแปรที่xฉันสร้างขึ้นเพื่อใช้ในห้องสมุดของฉัน


7
ระวังคำศัพท์ของคุณ การกำหนดเนมสเปซบ่งบอกว่าตัวแปรสามารถเข้าถึงได้จากภายนอกโดยกำหนดแอดเดรสเนมสเปซ (โดยทั่วไปจะใช้คำนำหน้า) แม้ว่าจะเป็นไปได้ใน Javascript ที่ไม่ได้แสดงให้เห็นที่นี่
Gareth

ฉันเห็นมันไม่ได้เป็นเหมือน namespace (function(){ ... return { publicProp1: 'blah' }; })();แต่คุณสามารถให้ทำงานที่คล้ายกันโดยกลับวัตถุที่มีคุณสมบัติที่คุณต้องการที่จะเผยแพร่ต่อไปนี้: เห็นได้ชัดว่าไม่ขนานกับการกำหนดเนมอย่างสมบูรณ์ แต่อาจช่วยให้คิดแบบนั้นได้
Joel

ในตัวอย่าง x ของคุณยังคงเป็นตัวแปรส่วนตัว ... แม้ว่าคุณจะห่อไว้ใน IIFE ไปข้างหน้าและพยายามเข้าถึง x ด้านนอกของฟังก์ชั่นที่คุณไม่สามารถ ..
RayLoveless

จุดของคุณไม่ถูกต้อง แม้ในฟังก์ชั่นต่อไปนี้ห้องสมุดอื่น ๆ ก็ไม่สามารถเข้าถึง x function () {var x = 2}
RayLoveless

@ RayLoveless ฉันเห็นด้วย ฉันไม่ได้ขัดแย้งยืนยันว่า ในความเป็นจริงฉันยืนยันเช่นเดียวกับประโยคสุดท้ายของคำตอบนี้
Joel

8

คุณสามารถใช้ฟังก์ชั่นการปิดเป็นข้อมูลในนิพจน์ที่ใหญ่ขึ้นเช่นเดียวกับในวิธีนี้ในการพิจารณาการรองรับเบราว์เซอร์สำหรับวัตถุ html5 บางส่วน

   navigator.html5={
     canvas: (function(){
      var dc= document.createElement('canvas');
      if(!dc.getContext) return 0;
      var c= dc.getContext('2d');
      return typeof c.fillText== 'function'? 2: 1;
     })(),
     localStorage: (function(){
      return !!window.localStorage;
     })(),
     webworkers: (function(){
      return !!window.Worker;
     })(),
     offline: (function(){
      return !!window.applicationCache;
     })()
    }

อะไร !! ทำ?
1.21 gigawatts

!! แปลงค่าให้เป็นการแทนค่าบูลีน (จริง / เท็จ)
เลียม

7

นอกเหนือจากการรักษาตัวแปรในตัวเครื่องแล้วการใช้งานที่สะดวกมากอย่างหนึ่งคือเมื่อเขียนไลบรารีโดยใช้ตัวแปรส่วนกลางคุณสามารถตั้งชื่อตัวแปรให้สั้นลงเพื่อใช้ภายในไลบรารี มักใช้ในการเขียนปลั๊กอิน jQuery เนื่องจาก jQuery อนุญาตให้คุณปิดการใช้งานตัวแปร $ ที่ชี้ไปที่ jQuery โดยใช้ jQuery.noConflict () ในกรณีที่มันถูกปิดใช้งานรหัสของคุณยังคงสามารถใช้ $ และไม่ทำลายถ้าคุณทำ:

(function($) { ...code...})(jQuery);

3
  1. เพื่อหลีกเลี่ยงการปะทะกันกับวิธีการ / ไลบรารีอื่น ๆ ในหน้าต่างเดียวกัน
  2. หลีกเลี่ยงขอบเขตส่วนกลางทำให้เป็นขอบเขตภายใน
  3. เพื่อให้การดีบักเร็วขึ้น (ขอบเขตโลคัล)
  4. JavaScript มีขอบเขตฟังก์ชันเท่านั้นจึงจะช่วยในการรวบรวมรหัสได้เช่นกัน

1

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

(function() {
    'use strict';

    //Your code from here
})();

ทำไมเราต้องใช้อย่างเข้มงวด
nbro

ตรวจสอบบทความนี้: stackoverflow.com/questions/1335851/…
Neha Jain

ไม่ตอบคำถามจริงๆ!
Pritam Banerjee

Pritam เป็นการใช้งานที่ดี โปรดทำวิจัยที่เหมาะสมก่อนที่จะลงคะแนนคำตอบใด ๆ
Neha Jain

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