ประกาศฟังก์ชั่นเป็น var แทนฟังก์ชั่น


28

มากขึ้นเรื่อย ๆ ฉันเห็นว่ามีการประกาศฟังก์ชั่นเช่นนี้

var foo = function() {

    // things
};

แทนที่จะเป็นวิธีที่ฉันได้เรียนรู้เช่น

function foo() {

    // things
}

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


เป็นที่น่าสังเกตว่าใน javascript ฟังก์ชั่นเป็นพลเมืองชั้นหนึ่ง สิ่งนี้ช่วยให้คุณสามารถส่งผ่านพฤติกรรมเช่นเดียวกับวัตถุ สิ่งนี้มีประโยชน์มากสำหรับการโทรกลับและการมอบหมายเหนือสิ่งอื่นใด
Chris Bye

ขอบเขต การตัดชื่อตัวแปร "// Things" นั้นสำคัญมาก / หวังว่าจะป้องกันการชนกันของชื่อ "// Things" ที่กำลังทำการตัดคำโดยมี JavaScript (ไฟล์) อื่นรวมอยู่ด้วย วิธีคิดอีกอย่างคือคุณได้สร้างเนมสเปซ "foo"
Radarbob

คำตอบ:


25

var foo = function() {} กำหนดตัวแปรที่อ้างอิงถึงฟังก์ชั่นที่ไม่ระบุชื่อ

function foo() {}fooกำหนดฟังก์ชันการตั้งชื่อ

สามารถส่งผ่านโดยชื่อเป็นพารามิเตอร์ฟังก์ชั่นและสามารถอินสแตนซ์หากการใช้งานที่ตั้งใจไว้สำหรับ OOP

ในตอนท้ายของวันสิ่งที่คุณใช้ส่วนใหญ่จะถูกกำหนดโดยกรณีการใช้งานเฉพาะของคุณ (Javascript สนุกเช่นนั้น;) หากคุณใช้อดีตฉันขอแนะนำให้คุณตั้งชื่อฟังก์ชั่น:

var foo = function MY_function() {}. หลักการตั้งชื่อนี้ช่วยให้การเรียกดีบักเกอร์ของคุณไม่ไร้ประโยชน์


1
มีข้อผิดพลาดที่มีในฟังก์ชั่น () ของฉัน ...
Erik Reppen

1
@Dessert Brecht และวิธีการเกี่ยวกับ var foo = function foo () {... } เข้าหา?
shabunc

@shabunc: แล้วมันล่ะ? มันอยู่ในย่อหน้าสุดท้ายของคำตอบของฉัน
Demian Brecht

@ Dessert Brecht ไม่จริงในตัวแปรย่อหน้าสุดท้ายถูกเรียกfooและฟังก์ชั่นที่เรียกว่าMY_function
shabunc

@shabunc: ชื่อไม่สำคัญ สิ่งที่สำคัญคือมูลค่าใน callstack ตัวอย่างเช่น [NAMESPACE] _ [fn name] เป็นแบบแผนที่ใช้โดย Mozilla ชื่อนั้นไม่สำคัญตราบใดที่การประชุมของคุณสอดคล้องกันตลอดทั้งโครงการของคุณ
Demian Brecht

13

ฟังก์ชั่นการแสดงออก:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

การแสดงออก func ในกรณีนี้ไม่ระบุชื่อ แต่ได้รับมอบหมายให้ var สำหรับการอ้างอิง นี่คือความแตกต่างจากคำสั่งฟังก์ชั่นที่มีข้อความในวิธีต่อไปนี้:

  • ไม่สามารถยกได้ (เรียกก่อนที่จะถูกกำหนด)
  • new someFunction().constructor.name === 'someFunction';//false อินสแตนซ์ไม่ได้รับชื่อ var สำหรับ constructor.name เนื่องจากการอ้างอิงไปยังฟังก์ชันได้รับการกำหนดให้กับ var แต่ var ไม่ใช่ฟังก์ชันที่เชื่อมโยงกับชื่อ var

ในคำสั่งฟังก์ชั่นที่มีข้อความ:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • งานยก
  • new someFunction().constructor.name === 'someFunction'; //true ชื่อถูกผูกเข้ากับฟังก์ชันโดยตรง

โดยทั่วไปการพูดไม่มีเหตุผลที่ดีในการแสดงออกเพื่อ var ยกเว้นว่าคุณต้องการให้การโทรล้มเหลวหากสิ่งต่าง ๆ ถูกเคลื่อนย้ายหรือคุณกำลังกำหนด / กำหนดวิธีการในหนึ่งบรรทัด ฉันพบว่าการยกมีประโยชน์สำหรับการจัดระเบียบวัตถุด้วย func ภายในและคำจำกัดความของวิธีการที่ด้านล่างเพื่อให้ฉันได้รับพฤติกรรมที่แท้จริงของวัตถุและทำคำจำกัดความวิธีสาธารณะหนึ่งบรรทัด (โดยการกำหนด funcs ให้this.กับชื่อเดียวกัน) ทั้งหมดในที่เดียว จุดเพื่อความสะดวกในการอ้างอิง คุณควรพยายามใช้คำแถลงที่มีข้อความสำหรับตัวสร้าง IMO เพื่อให้คุณสามารถระบุ 'ประเภท' ของวัตถุผ่านทางตัวสร้าง


8

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

ตัวอย่างเช่น:

SomeThing('abc', function(a,b) {return a*b;});

VS ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

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

ดูที่https://stackoverflow.com/questions/111102/how-do-javascript-closures-work


4

ความแตกต่างในทางปฏิบัติที่สำคัญคือการชัก ตัวอย่างเช่น:

foo(); // alerts 'hello'
function foo() {alert('hello');}

VS

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

นอกจากนี้นี่คือพฤติกรรมที่ไม่ได้กำหนด

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

ในขณะนี้ก็โอเค

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}

7
มีอะไรผิดปกติอย่างแน่นอนกับการกำหนดฟังก์ชั่นภายในฟังก์ชั่นใน JS มีหลายที่ที่คุณไม่สามารถกำหนดฟังก์ชันใน JS ได้
Erik Reppen

2
@ErikReppen แน่นอนคุณไม่สามารถใช้การประกาศฟังก์ชันภายในบล็อกที่ไม่ใช่ฟังก์ชัน (เช่นภายในคำสั่ง if) ฉันดูเหมือนจะไม่พบที่ฉันอ่านพวกเขาไม่สามารถใช้ในฟังก์ชั่นอื่น
ออสติน

@ Austin ไม่มีอะไรผิดปกติกับนิยามฟังก์ชั่นภายในifข้อความเช่นกัน!
ทิม

@Austin: บางทีคุณอ่านที่ w3schools? ;)
Demian Brecht

2
@ErikReppen ฟังก์ชันนิพจน์สามารถใช้ได้ทุกที่ ไม่สามารถประกาศฟังก์ชันได้ ดูstackoverflow.com/questions/10069204/…
ออสติน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.