Является ли 'Object' функцией в JavaScript?

Рассмотрим эту функцию:

function Foo(){
    var a = "3";
};

Согласно __proto__ VS. прототип в JavaScript,

Foo.__proto__ = Function.prototype
Function.prototype.__proto__ = Object.prototype

Я понял эту часть, но если я сделаю это в консоли Google Chrome:

Object.__proto__
output: ƒ () { /* native code */ }

Function.__proto__
output: ƒ () { /* native code */ }

Q1: почему они указывают на функцию? Что на самом деле представляют собой Function и Object и чем они отличаются друг от друга, потому что Объект на самом деле является функцией?

typeof Object
"function"

Q2: Если в JavaScript все является объектом, то почему Object является функцией? Кроме того, как функция на самом деле реализована внутри JavaScript? Что происходит с переменными, объявленными внутри функции? Функция преобразована в объект компилятором JavaScript?

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

Ответы

Ответ 1

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

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

В JavaScript все, что не является примитивом, является объектом. Это включает в себя функции, которые в основном представляют собой особый тип объекта, который можно "вызывать" с помощью синтаксиса ().

JavaScript предоставляет ряд встроенных функций различного назначения. Две такие функции называются Object и Function. Другими словами, Object - это функция, а значит, и "объект" (структура данных).

Давайте возьмем вашу функцию Foo в качестве примера:

function Foo() {
    var a = "3";
}

Foo это функция. Это означает, что Foo может быть вызван, например. var f = Foo(). В этом случае f будет undefined поскольку Foo ничего не возвращает.

Поскольку Foo является функцией, это также объект. Это означает, что мы также можем добавлять и читать свойства из него:

Foo.bar = 5;
Foo.bar++;
console.log(Foo.bar); // prints 6

Обратите внимание, что эта "объектная" часть Foo не связана с содержимым функции. Это означает, что код, который вы объявили (var a = "3"), не имеет значения. Вы не можете получить доступ к var a любым способом здесь, потому что он не существует, пока вы не вызовете функцию. Если вы выполняете Foo.a, вы не управляете var a внутри функции; вы работаете со свойством a над объектом Foo.

Однако вы можете сделать это наоборот и получить доступ к свойствам в Foo внутри функции:

function Foo() {
    var a = "3"; // a is local to this scope, you cannot get to it from outside
    console.log(a); // prints 3 - local variable a is accessible inside the scope of this function
    console.log(Foo.a); // prints 5 - a is a property on object Foo, and is accessible here
}
// var a inside Foo cannot be accessed here
Foo.a = 5;
Foo();

Редактировать: Re. Ваш вопрос по поводу "этого" в комментариях. this специальное ключевое слово в JavaScript, которое ссылается на объект. Однако этот объект не является самой функцией, это новый объект, который создается при вызове функции с помощью ключевого слова new:

function Bar() {
    this.a = 10;
    console.log(this == Bar); // prints false
}
var bar = new Bar();
console.log(bar.a); // prints 10

Функция, которая должна вызываться с new ключевым словом, называется "функцией конструктора". Object и Function являются примерами функций-конструкторов, поэтому их имена начинаются с заглавной буквы (соглашение в JavaScript).

Когда вы создаете объект с помощью функции конструктора, prototype свойства этой функции используется в качестве прототипа (доступного через __proto__) созданного объекта.

console.log(bar.constructor == Bar) // prints true
console.log(bar.__proto__ == Bar.prototype) // prints true

this также используется для других вещей, но это широкая тема и выход за рамки этого вопроса.

Ответ 2

Function и Object являются функциями-конструкторами, которые могут использоваться для создания функции и объекта, соответственно, что является причиной typeof Function возвращает function.

О том, как функции и объекты связаны в JavaScript, рассмотрим следующие моменты:

  1. Все не примитивные типы являются объектами в JavaScript.
  2. Все объекты прямо или косвенно наследуются от Object.prototype (если прототип не изменен явно с помощью setPrototypeOf).
  3. Все нативные функции наследуются от Function.prototype, который наследуется от Object.prototype, поэтому это означает, что функция косвенно наследуется от Object.prototype, потому что функции рассматриваются как объекты в JavaScript.
  4. Причиной того, что функции рассматриваются как объекты, является то, что они могут передаваться в качестве параметров другим функциям и могут быть возвращены из функций, то есть функций более высокого порядка (мощная функция javascript).
  5. Функцию можно вызывать с помощью оператора () поскольку механизм JavaScript знает, что она объявлена с использованием ключевого слова функции, и имеет исполняемый код. Таким образом, всякий раз, когда он вызывается, движок JavaScript создает новый контекст выполнения и устанавливает привязку this а затем выполняет функцию. Ничего из этого не происходит, когда вы пытаетесь вызвать объект, вместо этого выдается ошибка, т.е. "Это не функция".

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

  6. Так как функция рассматривается в JavaScript как объект, мы можем добавлять к ней свойства, создавать из нее новые объекты.
  7. Объект нефункционального типа нельзя вызвать с помощью () поскольку он не имеет исполняемого кода и не объявлен с использованием ключевого слова function. Вместо этого он объявляется с использованием new Object() или нотации объекта и содержит методы и свойства.

Я надеюсь, что это очищает оба вопроса.

Ответ 3

Q1: почему они указывают на функцию?

A1: потому что они функции. Function и Object - просто функции конструктора.

Функция является Function object. объект является Object object.

Q2: Если в JavaScript все является объектом, то почему Object является функцией?

A2: Потому что Object это просто функция конструктора.

typeof Object
// 'function'
typeof new Object()
// 'object'

И функция является экземпляром Function, так что делает функцию объектом.

(function(){}) instanceof Function
// true

Ответ 4

В корне

Functions имеют некоторый код, который может быть выполнен.
Object - это те, которые содержат данные.

Для класса Point имеющего x и y.

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    isOrigin() { return x == 0 && y == 0; }
}
let p = new Point();

Ответ 1

В этом случае p является object который содержит данные или другие функции.

p.isOrigin является функцией.

Точно так же класс Point сам по себе является function которая при запуске выдает p. Вот почему все классы, такие как Object и Functions являются functions точнее constructor functions.

Ответ 2

Если в JavaScript все является объектом, то почему Object является функцией?

То же, что ответ 1.

Кроме того, как функция на самом деле реализована внутри JavaScript?

Различные движки JavaScript будут иметь разные реализации. У них есть спецификации, которым они должны следовать.

Что происходит с переменными, объявленными внутри функции?

Не по теме. Каждая function выполняется с областью, которая содержит все данные для этих функций.

Функция преобразована в объект компилятором JavaScript?

Не уверен, что ты спрашиваешь.

Ответ 5

Справочник по ECMAScript очень хорош для ответов на такие вопросы.

  • https://www.ecma-international.org/ecma-262/9.0/index.html#sec-ecmascript-language-types - это точка входа о том, какие типы поддерживает язык, и вводится понятие, что все, что есть, является либо довольно стандартное значение (логическое значение, строка и т.д.), либо объект. Но никаких дальнейших типов.
  • https://www.ecma-international.org/ecma-262/9.0/index.html#sec-object-type объясняет тип объекта. По сути, это набор атрибутов и/или методов доступа (например, getter/setter). Это также вводит термин "функциональный объект".
  • https://www.ecma-international.org/ecma-262/9.0/index.html#sec-object-internal-methods-and-internal-slots показывает внутреннюю семантику, внутренние методы и т.д. объектов. В конце этого раздела, в частности, описаны специфические внутренние элементы "функционального объекта" ("Call" и "Construct"), включая небольшие детали, такие как конструктор, являющийся необязательным.

Следовательно, чтобы ответить на ваш вопрос: Foo может быть ничем иным, как объектом (потому что все остальное в меню является базовым типом значения). Следовательно, Foo() - это специальный синтаксис, который просто вызывает внутренний метод Call этого объекта. Но Foo сам по себе является объектом насквозь, вы можете делать с ним все остальное, что вы можете делать с любым другим объектом, включая установку на него произвольных атрибутов.

Наличие метода, определенного для объекта, просто означает, что существует атрибут с этим именем, и этот атрибут ссылается на объект, который оказывается "функциональным объектом".

Что-то, что можно использовать в качестве конструктора, опять же, просто объект, у которого есть внутренний метод Construct и синтаксический сахар для его вызова.

Как вы знаете, в JavaScript нет классов, это объектно-ориентированный язык, основанный на прототипах (он настолько объектно-ориентирован, насколько вы можете понять, в нем буквально больше ничего нет). Таким образом, любой "прототип" - это просто связь между объектами. Метод конструктора (как объяснено в приведенной выше ссылке) просто вызывает метод конструктора с объектом, для которого он был вызван (т.е. Что-то вроде String), в качестве аргумента, точно так же, как язык будет вызывать Call при this объект является методом был вызван на.

Ответ 6

Object является функцией конструктора всех объектов. Итак, typeof Object==="function"

Вот фрагмент для визуализации:

console.log(typeof Object)            //function (which is an object)
var object=new Object()               //An instance of Object 'class'
console.log(typeof object)            //object
console.log(object instanceof Object) //true, because object is created by Object()

Ответ 7

Да, объект имеет тип функции. Это реализация класса/функции, которая при вызове с new (new Object()) приводит к объекту с выделенной памятью.