Что подразумевается под «первоклассным объектом»?

146

В недавнем вопросе я получил предложения поговорить, помимо прочего, об аспекте JavaScript, где функции являются объектами «первого класса». Что означает «первый класс» в этом контексте, в отличие от других объектов?

РЕДАКТИРОВАТЬ (Jörg W Mittag): точный дубликат: «Что такое первоклассная программная конструкция?»

ProfK
источник

Ответы:

179

Цитировать Википедию :

В информатике говорят, что язык программирования поддерживает первоклассные функции (или функциональные литералы), если он рассматривает функции как первоклассные объекты. В частности, это означает, что язык поддерживает создание новых функций во время выполнения программы, сохранение их в структурах данных, передачу их в качестве аргументов другим функциям и возврат их в качестве значений других функций.

Эта страница также прекрасно иллюстрирует это:

На самом деле, как и любая другая переменная

  • Функция является экземпляром типа Object
  • Функция может иметь свойства и иметь ссылку на метод конструктора.
  • Вы можете сохранить функцию в переменной
  • Вы можете передать функцию в качестве параметра другой функции
  • Вы можете вернуть функцию из функции

также прочитайте комментарий TrayMan, интересно ...

Сандер Верслуйс
источник
11
Цитировать Википедию приятно и модно, но описание написано на языке для ученых, а не для гиков. Какого черта все это значит? Последнее предложение в этой цитате - вагу.
Спойк
1
@Spoike, правда ... предоставленный ресурс javascript.
Сандер Верслуйс
16
Удобно, что язык, который имеет функции первого класса, также имеет функции более высокого порядка, в отличие от того, чтобы быть ограниченным функциями первого порядка, которые исключали бы функции первого класса. (Хотя возможен и более высокий порядок, не первоклассный.)
TrayMan
5
Я не нашел ничего неясного в цитате Википедии, но дополнительная ссылка превосходна.
ProfK
4
Ссылка больше не работает (примерно через 8 лет).
doubleOrt
47

Понятие «первоклассные функции» в языке программирования было введено британским ученым-программистом Кристофером Стрейчи в 1960-х годах. Наиболее известная формулировка этого принципа, вероятно, содержится в Структуре и интерпретации компьютерных программ Джеральда Джея Суссмана и Гарри Абельсона:

  • Они могут быть названы переменными.
  • Они могут быть переданы в качестве аргументов процедур.
  • Они могут быть возвращены как результаты процедур.
  • Они могут быть включены в структуры данных.

По сути, это означает, что вы можете делать с функциями все, что вы можете делать со всеми другими элементами в языке программирования. Таким образом, в случае JavaScript это означает, что все, что вы можете делать с Integer, String, Array или любым другим типом Object, вы также можете делать с функциями.

Йорг Миттаг
источник
14

Более полное одобрение формулировки Стрейчи-Суссмана-Абельсона. Так что, если ваш язык поддерживает такую ​​конструкцию, то у вас есть функция в качестве первоклассного языка :)

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... :)

Короче говоря, все является первоклассным объектом, если оно действует на языке как манипуляция состоянием типа объекта или типа объекта. Просто то, что вы можете оперировать и передавать заявления и оценивать в выражениях одновременно. Или даже короче: когда вы можете рассматривать функцию как объект, который может быть вызван дополнительно.

Арман Макхитариан
источник
9

Функции JavaScript - это функции первого класса, означающие, что функции и объекты рассматриваются как одно и то же. Функции могут быть сохранены как переменная внутри объекта или массива, а также могут быть переданы в качестве аргумента или возвращены другой функцией. Это делает функцию «первоклассными гражданами в JavaScript»

JavaScript использует синтаксис буквальной нотации, что затрудняет полное понимание того факта, что в JavaScript функции являются объектами.

Например..

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

оба declerations эквивалентны. Используя newмы вызываем функцию конструктора объекта. Также с помощью {}(JavaScript-ярлык, называемый литералами) мы вызываем функцию построения объекта. {}это просто более короткое представление для создания экземпляра конструктора.

Большинство языков использует newключевое слово для создания объекта, поэтому давайте создадим объект JavaScript.

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

Как вы видите , мы создали имя объекта функции .

Создание той же функции имени объекта с использованием выражения функции JavaScript.

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

Здесь мы только что создали функцию имени объекта.

Марк Адлер
источник
9

В JavaScript функции являются объектами первого класса, потому что они могут делать гораздо больше, чем объекты.

  • Функция является экземпляром типа Object.

Function instanceof Object //returns true

Как и объект, функция может иметь свойства и иметь ссылку на свою функцию конструктора.

 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 

  • Функции могут быть сохранены в переменной как значение.

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

  • Функции могут быть переданы в качестве аргументов другим функциям

function callback (foo){
      foo();
}

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

  • Вы можете вернуть функцию из функции

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

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

  • Может быть сохранен в переменной в качестве ссылки.

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

Сагар Мунджал
источник
Объект может сделать все это также.
doubleOrt
5

Простой тест. Если вы можете сделать это на своем языке (например, Python):

def double(x):
    return x*x

f = double

print f(5) #prints 25

Ваш язык рассматривает функции как объекты первого класса.

Ювал Адам
источник
3
Но я могу сделать это в C ++: int дважды (int x) {return x << 1; } int (* f) (int) = дважды; станд :: соиЬ << (* е) (5) << станд :: епсИ; Означает ли это, что C ++ рассматривает функции как объекты первого класса (со смешным синтаксисом)?
Thomas L Holaday
1
Пока вы можете создать функцию внутри функции, я хочу сказать нет.
Чао
1
Указатели на функции C поддерживают (очень ограниченное определение) функции первого класса, но функции не являются объектами. Указатели на функции в C не содержат состояния или поведения.
Стивен Крамер
2

Это означает, что функции являются объектами с типом и поведением. Их можно динамически создавать, передавать как любой другой объект, и тот факт, что их можно вызывать, является частью их интерфейса.

cadrian
источник
2

Это означает, что функция фактически наследуется от Object. Так что вы можете передать его и работать с ним, как с любым другим объектом.

Однако в c # вам нужно воздерживаться от делегатов или рефлексии, чтобы поиграться с функциями. (это стало намного лучше в последнее время с лямбда-выражениями)

Rashack
источник
2

Определение на сайте Mozilla является кратким и ясным. Согласно им,

В JavaScript функции являются объектами первого класса, потому что они могут иметь свойства и методы, как и любой другой объект . Что отличает их от других объектов, так это то, что функции могут быть вызваны. Вкратце, они являются объектами Function.

И

функция - это «подпрограмма», которая может вызываться внешним (или внутренним в случае рекурсии) кодом функции. Как и сама программа, функция состоит из последовательности операторов, называемых телом функции. Значения могут быть переданы функции, и функция вернет значение.

Arpit
источник
0

Я думаю, когда что-то является первым классом в языке, это означает, что это поддерживается его синтаксисом, а не библиотекой или синтаксическим сахаром. например, классы в C не являются первоклассными

Цзян Цю
источник
0

Простые в JavaScript функции - это объекты первого класса, то есть функции имеют тип Object, и их можно использовать первоклассным образом, как и любой другой объект (String, Array, Number и т. Д.), Поскольку они на самом деле являются объектами. самих себя. Они могут «храниться в переменных, передаваться в качестве аргументов функциям, создаваться внутри функций и возвращаться из функций».

Santi
источник