Javascript: функция и объект...?

Можно ли вызвать функцию как объект? Например:

function Tip(txt){      
    this.content = txt;  
    this.shown = false;  
}

и

var tip = new Tip(elem.attr('title'));

Мои вопросы:

  • Можете ли вы назвать new для функции, как для объекта?
  • Использование "this" стало возможным, поскольку мы используем эту функцию как объект?

Ответ 1

Вы ищете концепцию constructor.

Все функции в JavaScript являются объектами и могут использоваться для создания объектов:

function make_person(firstname, lastname, age) {
    person = {};
    person.firstname = firstname;
    person.lastname = lastname;
    person.age = age;
    return person;
}
make_person("Joe", "Smith", 23);
// {firstname: "Joe", lastname: "Smith", age: 23}

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

function make_person_object(firstname, lastname, age) {
    this.firstname = firstname;
    this.lastname = lastname;
    this.age = age;
    // Note, we did not include a return statement
}

Ключевое отличие от make_person и make_person_object заключается в том, что вызов new make_person() (в отличие от простого make_person()) не будет делать ничего другого... оба будут производить один и тот же объект. Однако вызов make_person_object() без оператора new будет определять ваши атрибуты this для текущего объекта this (обычно window, если вы работаете в браузере.)

Таким образом:

var Joe = make_person_object("Joe", "Smith", 23);
console.log(Joe); // undefined
console.log(window.firstname) // "Joe" (oops)

var John = new make_person_object("John", "Smith", 45);
console.log(John); // {firstname: "John", lastname: "Smith", age: 45}

Кроме того, как указывает @RobG, этот способ делать вещи создает ссылку на свойство prototype make_person_object для каждого созданного нами "Человека". Это позволяет нам добавлять методы и атрибуты людям после факта:

 // Assuming all that came before
make_person_object.prototype.full_name = "N/A";
make_person_object.prototype.greet = function(){ 
    console.log("Hello! I'm", this.full_name, "Call me", this.firstname); 
};
John.full_name // "N/A"
John.full_name = "John Smith"; 
make_person_object.full_name // Still "N/A"
John.greet(); // "Hello! I'm John Smith Call me John"

В Конвенции утверждается, что функции-конструкторы, такие как make_person_object, являются заглавными, сингулярными и "обозначенными" (из-за отсутствия лучшего термина) - таким образом, у нас будет конструктор Person, а не make_person_object, который может быть ошибочно принимается за обычную функцию.

См. также:

Ответ 2

Каждая функция имеет ссылку на this. если вы вызываете Tip(), this будет ссылаться на глобальный объект. Если вы вызываете new Tip(), создается новый объект со ссылкой на Tip.prototype и this будет ссылаться на этот новый объект.

Вы не можете использовать new для объектов, например new {} throws TypeError: object is not a function. Если вы ссылаетесь на new Object(), то это работает, поскольку Object является функцией.

Ответ 3

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

Если вы хотите добавить функции в объект Tip, вы должны добавить их в Tip-прототип, например:

Tip.prototype.getContent = function() {
    return this.content;
};

Если у вас есть это, и тогда вы выполните:

var tip = new Tip("this  is my content.");
alert(tip.getContent());

Появится сообщение, в котором говорится: "Это мой контент".

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

var Tip = { content: txt, show: false };
var tipObj = new Tip();

Ответ 4

Функция действует как конструктор на классе. В качестве альтернативы вы можете:

function Tip(txt) {
 return {
 content: txt,
 shown: false
}
}

и получить новый экземпляр с помощью: var myTip = new Tip("my epic tip"); Это похоже на, скажем, С#:

public class Tip {
string text = "";
public Tip(string txt) {
text = txt;
}
}

Итак, вроде. 1) Вы вызываете новое, поскольку функция по существу действует как класс, а 2) this ссылается на текущий экземпляр класса.

Ответ 5

для # 1: существует объект, называемый Function (capital F)

var f = new Функция ( "x", "y", "return x * y;" );

для # 2: "this" отличается в зависимости от шаблона innvocation (как это называется Дугласом Крокфордом). Крокфорд сказал, что существует 4 шаблона (шаблон метода, шаблон функции, шаблон конструктора и шаблон "применить" )

Ответ 6

  • Фактически, все типы данных, такие как array, являются объектами.
  • Когда мы принимаем функцию как объявление класса, это работает.

Ответ 7

Я изо всех сил пытался понять эти понятия (функции как объекты, объекты-прототипы, свойство __proto__, свойство конструктора) почти 8 лет (2008-2016 гг.). Сначала я начал работу с Дэвидом Фланаганом "Окончательное руководство по JavaScript 5/6th ed" в течение 4-5 лет после нескольких чтений глав 6, 8, 9; это не имело для меня никакого смысла, но после борьбы в Интернете я понял, что можно управлять функциями (типичная функция С++ со свойствами) в качестве объектов; потому что объект также может иметь методы. И, к счастью, в 7-м году 2015 года я начал Wrox Николаса К. Закаса "Профессиональный JavaScript для веб-разработчиков 3-го изд." Глава 6,7; и было очень полезно понять выше четырех понятий. Традиционно в C/С++/С# предполагается, что функции модифицируют объект; или, другими словами, они сделаны для "выполнения чего-либо", когда объекты созданы для поддержания состояния глобального контекста работы с методами изменения собственного состояния объекта. Итак, если функции могут быть объектами первого класса, то почему объекты не могут быть похожими на функции?

Главный ключевой вопрос здесь должен быть ПОЧЕМУ? Почему не один концептуальный объект  как "ассоциативная функция" или "цепные аргументы"? И вот мое понимание: Browser exe - однопоточное приложение, и этот exe управляет вызовом JS-интерпретатора с предопределенной цепочкой областей (некоторые из которых похожи на строку команд с аргументами); теперь во время выполнения JS-движок (не интерпретатор) загружает код в режиме подъема (так как нет основного метода, так что он поднимает хорошо определенные коды с ключевыми словами и его вызов). В этом повышаемом коде, если функции не обрабатываются как объекты, их необходимо поддерживать в отдельном контексте вызова (вне цепочки видимости), что легко возможно в c/С++/С# (bcoz из нескольких потоков и неограниченной памяти), но не в JS, Следовательно, "to-do smth on clained object" делает функцию java script как объект первого класса. На самом деле объекты JS тоже делают то же самое; единственное различие заключается в том, что "вызов объекта" не существует в объектах, где "вызов функции" является целым контекстом, который имеет смысл. Функции также можно рассматривать как "набор переменных с инструкциями на языке ассемблера с адресной ссылкой (цепочкой)". Связующая часть - это другая сторона сюжета в виде верхнего → нижнего связывания (объекта прототипа) и нижней → верхней ссылки (свойство __ proto__) против объекта blue print- > экземпляра объекта (свойство конструктора). Несколько месяцев назад я нашел следующее изображение полезным для понимания ссылок.

http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png "Модель объекта JS"