"Đối tượng hạng nhất" nghĩa là gì?


146

Trong một câu hỏi gần đây , tôi đã nhận được các đề xuất để nói về, trong số những thứ khác, khía cạnh của JavaScript trong đó các hàm là các đối tượng 'hạng nhất'. 'Lớp đầu tiên' có nghĩa là gì trong bối cảnh này, trái ngược với các đối tượng khác?

EDIT (Jörg W Mittag): Chính xác trùng lặp: "Cấu trúc lập trình lớp đầu tiên là gì?"


Câu trả lời:


179

Để trích dẫn Wikipedia :

Trong khoa học máy tính, một ngôn ngữ lập trình được cho là hỗ trợ các hàm hạng nhất (hoặc hàm chữ) nếu nó xử lý các hàm như các đối tượng hạng nhất. Cụ thể, điều này có nghĩa là ngôn ngữ hỗ trợ xây dựng các hàm mới trong quá trình thực thi chương trình, lưu trữ chúng trong các cấu trúc dữ liệu, chuyển chúng làm đối số cho các hàm khác và trả về chúng làm giá trị của các hàm khác.

Trang này cũng minh họa nó rất đẹp:

Thực sự, giống như bất kỳ biến nào khác

  • Hàm là một thể hiện của loại Đối tượng
  • Một hàm có thể có các thuộc tính và có một liên kết quay lại phương thức constructor của nó
  • Bạn có thể lưu trữ hàm trong một biến
  • Bạn có thể truyền hàm dưới dạng tham số cho hàm khác
  • Bạn có thể trả về hàm từ một hàm

cũng đọc bình luận của Khayman, thú vị ...


11
Trích dẫn wikipedia là tốt đẹp và bảnh bao, nhưng mô tả được viết bằng ngôn ngữ cho các nhà khoa học chứ không phải cho các chuyên viên máy tính. Tất cả điều đó có nghĩa là gì? Câu cuối cùng trong trích dẫn đó là vagu.
Spoike

1
@Spoike, đúng ... cung cấp tài nguyên javascript.
Sander Versluys

16
Thuận tiện một ngôn ngữ có chức năng hạng nhất cũng có chức năng bậc cao, trái ngược với việc bị giới hạn ở chức năng hạng nhất, sẽ loại trừ các chức năng hạng nhất. (Mặc dù có thứ tự cao hơn, nhưng không phải hạng nhất là có thể.)
Khayman

5
Tôi không tìm thấy gì không rõ ràng trong trích dẫn Wikipedia, nhưng liên kết bổ sung là tuyệt vời.
ProfK

4
Liên kết không hoạt động nữa (sau 8 năm).
doubleOrt

47

Khái niệm "chức năng hạng nhất" trong ngôn ngữ lập trình được giới thiệu bởi nhà khoa học máy tính người Anh Christopher Strachey vào những năm 1960. Công thức nổi tiếng nhất của nguyên tắc này có lẽ là trong Cấu trúc và diễn giải các chương trình máy tính của Gerald Jay Sussman và Harry Abelson:

  • Chúng có thể được đặt tên theo các biến.
  • Họ có thể được thông qua như là đối số để làm thủ tục.
  • Họ có thể được trả lại như là kết quả của các thủ tục.
  • Chúng có thể được bao gồm trong cấu trúc dữ liệu.

Về cơ bản, điều đó có nghĩa là bạn có thể làm với các chức năng mọi thứ bạn có thể làm với tất cả các yếu tố khác trong ngôn ngữ lập trình. Vì vậy, trong trường hợp JavaScript, điều đó có nghĩa là mọi thứ bạn có thể làm với Integer, String, Array hoặc bất kỳ loại Object nào khác, bạn cũng có thể thực hiện với các hàm.


14

Phê duyệt đầy đủ hơn về công thức của Strachey-Sussman-Abelson. Vì vậy, nếu ngôn ngữ của bạn hỗ trợ cấu trúc như vậy thì bạn đã có chức năng là ngôn ngữ hạng nhất :)

var men = function (objectOfAdmiration) {
  return objectOfAdmiration();
};
men.isSweetHeart = true;

var women = function (objectOfAdmiration) {
  return objectOfAdmiration();
};
women.isSweetHeart = true;

var aliens = function (objectOfAdmiration) {
  return objectOfAdmiration();
};

function like(obj){
  if (obj.isSweetHeart) {
      return function (){ return "Holy TRUE!"}; 
  }
  else {
      return function (){ return "Holy CRAP!"};
  }
}

alert("Men like women is " + men(like(women))); // -> "Holly TRUE!"
alert("Women like men is " + women(like(men))); // -> "Holly TRUE!"

alert("Men like aliens is " + men(like(aliens))); // -> "Holly CRAP!"
alert("Aliens like women is " + aliens(like(women))); // -> "Holly TRUE!" :)

//women(like(aliens)); //  Who knows? Life is sometimes so unpredictable... :)

Nói tóm lại, bất cứ thứ gì cũng là một đối tượng hạng nhất nếu nó hoạt động trong ngôn ngữ như một loại thao tác trạng thái của loại đối tượng hoặc loại đối tượng. Đơn giản chỉ cần một cái gì đó bạn có thể thao tác và chuyển xung quanh các câu lệnh và đánh giá các biểu thức cùng một lúc. Hoặc thậm chí ngắn hơn: khi bạn có thể nghĩ về một chức năng như một đối tượng có thể được gọi thêm.


9

Các hàm JavaScript là các hàm hạng nhất có nghĩa là các hàm và các đối tượng được coi là cùng một thứ. Các hàm có thể được lưu trữ dưới dạng một biến bên trong một đối tượng hoặc một mảng cũng như nó có thể được truyền dưới dạng một đối số hoặc được trả về bởi một hàm khác. Điều đó làm cho chức năng "công dân hạng nhất trong JavaScript"

JavaScript sử dụng cú pháp ký hiệu theo nghĩa đen khiến bạn khó có thể nắm bắt hoàn toàn thực tế rằng trong các hàm JavaScript là các đối tượng.

Ví dụ..

var youObj1 = new Object();
// or
var youObj1 = {};

cả hai giải mã đều tương đương. Bằng cách sử dụng, newchúng ta đang gọi hàm xây dựng của một đối tượng. Cũng bằng cách sử dụng {}(phím tắt JavaScript được gọi là chữ), chúng tôi đang gọi hàm xây dựng của một Đối tượng. {}chỉ là một đại diện ngắn hơn để khởi tạo hàm tạo.

Hầu hết các ngôn ngữ sử dụng newtừ khóa để tạo một đối tượng, vì vậy hãy tạo một đối tượng JavaScript.

var myFunction = new Function("a",  "b", 'return a_b');

Như bạn thấy chúng ta đã tạo một hàm tên đối tượng .

Tạo chức năng tên đối tượng tương tự bằng cách sử dụng biểu thức hàm JavaScript ..

var myFunction = function myFunction(a,b) {
    return a+b;
}

Ở đây chúng ta chỉ cần tạo một hàm tên đối tượng.


9

Trong các hàm javascript là các đối tượng hạng nhất vì nó có thể làm được nhiều hơn những gì đối tượng có thể làm.

  • Hàm là một thể hiện của một loại Object.

Function instanceof Object //returns true

Giống như một đối tượng, một hàm có thể có các thuộc tính và có thể có một liên kết trở lại hàm tạo của nó.

 var o = {}; // empty object 'o'
    o.a = 1 ; 
    o.b = 2 ; 

    console.log(o.a); // 1
    console.log(o.b); // 2 


    function foo(){};
    foo.a = 3 ; 
    foo.b = 4 ; 

    console.log(foo.a);  // logs 3
    console.log(foo.b);  // logs 4 

  • Các hàm có thể được lưu trữ trong một biến như một giá trị.

  var foo = function(){}; 
    console.log(foo); // function(){}

  • Các hàm có thể được truyền dưới dạng đối số cho các hàm khác

function callback (foo){
      foo();
}

callback(function(){console.log('Successfuly invoked as an argument inside function callback')})

  • Bạn có thể trả về một chức năng từ một chức năng

 function foo(){
	    return function(){console.log('working!')};
    }

    var bar = foo();
    bar(); // working!

  • Có thể được lưu trữ trong một biến như một tài liệu tham khảo.

    var sum = function (a,b){return a+b}  
    sum(4,4);


Một đối tượng có thể làm tất cả điều đó là tốt.
doubleOrt

5

Kiểm tra đơn giản. Nếu bạn có thể làm điều này bằng ngôn ngữ của bạn (ví dụ Python):

def double(x):
    return x*x

f = double

print f(5) #prints 25

Ngôn ngữ của bạn đang xử lý các chức năng như các đối tượng hạng nhất.


3
Nhưng tôi có thể làm điều này trong C ++: int hai lần (int x) {return x << 1; } int (* f) (int) = hai lần; std :: cout << (* f) (5) << std :: endl; Điều đó có nghĩa là C ++ coi các hàm là các đối tượng hạng nhất (với một cú pháp vui nhộn)?
Thomas L Holaday

1
Cho đến khi bạn có thể tạo một chức năng bên trong một chức năng, tôi muốn nói không.
cHao

1
Con trỏ hàm C hỗ trợ (một định nghĩa rất hạn chế) các hàm hạng nhất nhưng các hàm không phải là đối tượng. Các con trỏ hàm trong C không chứa trạng thái hoặc hành vi.
Steven Kramer

2

Nó có nghĩa là các hàm là các đối tượng, với một loại và một hành vi. Chúng có thể được xây dựng linh hoạt, được truyền xung quanh như bất kỳ đối tượng nào khác và thực tế là chúng có thể được gọi là một phần của giao diện của chúng.


2

Nó có nghĩa là chức năng thực sự kế thừa từ Object. Vì vậy, bạn có thể vượt qua nó và làm việc với nó như với bất kỳ đối tượng nào khác.

Tuy nhiên, trong c #, bạn cần phải kiềm chế các đại biểu hoặc phản xạ để chơi xung quanh với các chức năng. (điều này trở nên tốt hơn gần đây với các biểu thức lambda)


2

Định nghĩa trên trang web Mozilla là ngắn gọn và rõ ràng. Theo họ,

Trong JavaScript, các hàm là các đối tượng hạng nhất, bởi vì chúng có thể có các thuộc tính và phương thức giống như bất kỳ đối tượng nào khác . Điều phân biệt chúng với các đối tượng khác là các chức năng có thể được gọi. Tóm lại, chúng là các đối tượng Hàm.

một hàm là một "chương trình con" có thể được gọi bằng mã bên ngoài (hoặc bên trong trong trường hợp đệ quy) cho hàm. Giống như chính chương trình, một hàm bao gồm một chuỗi các câu lệnh được gọi là thân hàm. Các giá trị có thể được truyền cho một hàm và hàm sẽ trả về một giá trị.


0

Tôi đoán khi một cái gì đó là lớp đầu tiên trong một ngôn ngữ, nó có nghĩa là nó được hỗ trợ bởi cú pháp của nó chứ không phải là một thư viện hoặc đường cú pháp. ví dụ, các lớp trong C không phải là lớp đầu tiên


0

Đơn giản trong JavaScript, các hàm là các đối tượng hạng nhất, các hàm thuộc loại Object và chúng có thể được sử dụng theo cách thức hạng nhất như bất kỳ đối tượng nào khác (String, Array, Number, v.v.) vì chúng thực sự là các đối tượng chúng tôi. Chúng có thể được lưu trữ trong các biến, được truyền dưới dạng đối số cho hàm, được tạo trong hàm và được trả về từ hàm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.