Как получить имя объекта js
Перейти к содержимому

Как получить имя объекта js

  • автор:

Как получить имя объекта js

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

Re: получить имя объекта — javascript

От: .
Дата: 05.10.07 14:53
Оценка:

Hard_Club wrote:

> Я в функцию передаю различные объекты для дальнейшего их анализа. Как
> можно узнать имя объекта, который был передан в функцию во внутренностях
> функции?
У объектов в javascript нет имён, да и не могу вспомнить язык где есть.

Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: получить имя объекта — javascript

От: Аноним
Дата: 06.10.07 02:49
Оценка:

Здравствуйте, Hard_Club, Вы писали:

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

Если у объекта есть свойство name, то так: obj.name.
Возможно, ты имел ввиду elem.tagName, elem.id, elem.className или что-то в этом роде.

Re: получить имя объекта — javascript

От: Flamer http://users.livejournal.com/_flamer_/
Дата: 06.10.07 09:33
Оценка:

Здравствуйте, Hard_Club, Вы писали:

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

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

myobj.myOwnName = 'supa-pupa object'; function analyze(obj) < if(obj.myOwnName == 'supa-pupa object') alert('Gotcha!'); >

Если надо узнать тип элемента, то есть свойство tagName, которое вернет имя HTML-тэга для элемента. Также есть свойство id, которое вернет значение атрибута id элемента. Есть свойство className, которое вернет назначенное элементу имя класса CSS.

В общем — колитесь, для чего это нужно, и будет больше конкретики

Function.name

Read-only свойство name глобального объекта Function и его экземпляров содержит название функции созданное во время определения функции или присваивания ссылки на функцию переменной, свойству, аргументу и т. п. Для анонимных функций это свойство может иметь значение «anonymous» или пустую строку «» .

Интерактивный пример

Интерактивные примеры размещены в GitHub репозитории. Если вы хотите добавить свои примеры, то клонируйте https://github.com/mdn/interactive-examples и пришлите пул реквест.

Атрибуты свойства Function.name
Записываемое нет
Перечисляемое нет
Настраиваемое да

Примечание: Заметьте, что в нестандартном, pre-ES2015 релизе configurable свойство было false

Примеры

Имя объявленной функции

Свойство name возвращает имя функции, либо пустую строку для анонимных функций:

function doSomething() > alert(doSomething.name); // выведет "doSomething" 

Имя функции-конструктора

Функции, созданные синтаксисом new Function(. ) или просто Function(. ) создают Function и имеют name «anonymous»:

new Function().name; // "anonymous" 

Предполагаемые имена функций

Переменные и методы могут предположить название анонимной функции из её синтаксической позиции (new in ECMAScript 2015).

var f = function () >; var object =  someMethod: function () >, >; console.log(f.name); // "f" console.log(object.someMethod.name); // "someMethod" 

Вы можете определить функцию с именем в function expression:

var object =  someMethod: function object_someMethod() >, >; console.log(object.someMethod.name); // выведет "object_someMethod" try  object_someMethod; > catch (e)  console.log(e); > // ReferenceError: object_someMethod is not defined 

Вы не можете изменить имя функции, это свойство только для чтения:

var object =  // анонимная функция someMethod: function () >, >; object.someMethod.name = "otherMethod"; alert(object.someMethod.name); //someMethod 

Для изменения name можно использовать Object.defineProperty() .

Сокращённые имена методов

var o =  foo() >, >; o.foo.name; // "foo"; 

Имена функций после привязки

Function.bind() производит функцию, получающую имя «bound и название самой функции.

function foo() > foo.bind(>).name; // "bound foo" 

Имена функций для getters и setters

Когда используются get и set, «get» и «set» появятся в имени функции.

let o = < get foo()<>, set foo(x)<> >; var descriptor = Object.getOwnPropertyDescriptor(o, "foo"); descriptor.get.name; // "get foo" descriptor.set.name; // "set foo";

Имена функций-классов

Можно использовать obj.constructor.name чтобы проверить «class» объекта (читайте предупреждение ниже):

function Foo() <> // ES2015 Syntax: class Foo <> var fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs "Foo"

Предупреждение: Интерпретатор объявит встроенное Function.name свойство только если функция не имеет своего собственного свойства name (см. 9.2.11 of the ECMAScript2015 Language Specification). Однако, в ES2015 статичные методы перезаписывают OwnProperty конструкторов класса-функции (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).

Таким образом, нельзя получить доступ к name любого класса со статичным свойством name():

class Foo  constructor() > static name() > > 

Со static name() методом Foo.name больше не содержит название класса, но отсылает к функции name() . Приведённое выше определение класса в ES2015 будет вести себя в Chrome и Firefox как в ES5:

function Foo() <> Object.defineProperty(Foo, 'name', < writable: true >); Foo.name = function() <>;

Пытаясь получить доступ к fooInstance с помощью fooInstance.constructor.name не даст название класса, но выведет метод name() . Пример:

let fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs function name()

Из ES5 syntax примера также видно, что в Chrome или Firefox статичное определение Foo.name становится записываемым (writable). Встроенное определение в отсутствии кастомного статичного методадоступно только для чтения:

Foo.name = 'Hello'; console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.

Следовательно не ожидайте, что Function.name свойство будет всегда содержать имя класса.

Имена функций-символов

Если у Symbol объявляется имя, то название метода — это имя квадратных скобках.

let sym1 = Symbol("foo"); let sym2 = Symbol(); let o =  [sym1]: function () >, [sym2]: function () >, >; o[sym1].name; // "[foo]" o[sym2].name; // "" 

JavaScript минифицированный

Предупреждение: Будьте осторожны, используя Function.name и изменения source кода с помощью JavaScript compressors (minifiers) или обфускаторов. Эти инструменты часто используются, как встроенные в JavaScript build pipeline, чтобы сократить размер билда перед деплоем в production. Такие трансформации часто изменяют имена функций.

Такой source code:

function Foo() <>; let foo = new Foo(); if (foo.constructor.name === ‘Foo’) < console.log("'foo' is an instance of 'Foo'"); >else

может быть сжат в:

function a() <>; let b = new a(); if (b.constructor.name === ‘Foo’) < console.log("'foo' is an instance of 'Foo'"); >else

В несжатой версии код выполняется ожидаемо «‘foo’ is an instance of ‘Foo'» . В то время, как в сжатой версии он ведёт себя иначе. Если вы полагаетесь на Function.name , как в примере, то убедитесь, что pipeline не меняет код или не ожидайте от функции определённого имени.

Спецификации

Specification
ECMAScript Language Specification
# sec-function-instances-name

Совместимость с браузерами

BCD tables only load in the browser

Курсы javascript

Нужно что-то про тот объект знать.
И знать кто его родитель.
Иначе как его искать?

var obj= < A: 1, B: 2, >let name='obj'; alert(JSON.stringify(window[name]));

11.03.2021, 14:40
Новичок на форуме
Регистрация: 05.03.2021
Сообщений: 8

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

Можно решить эту проблему, просто обновив инвентарь после загрузки игры.

for(var i=1, i if (инвентарь[i] !== null) инвентарь[i] = предметы[инвентарь[i]];
>
>

Но проблема в том, что «инвентарь[i]» (содержимое: инвентарь[нож]) является объектом, поэтому такая запись добавляет в инвентарь null. Если как-то преобразовать «инвентарь[i]» в строку, то все будет работать как нужно.

Объекты

Как мы знаем из главы Типы данных, в JavaScript существует 8 типов данных. Семь из них называются «примитивными», так как содержат только одно значение (будь то строка, число или что-то другое).

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

Объект может быть создан с помощью фигурных скобок с необязательным списком свойств. Свойство – это пара «ключ: значение», где ключ – это строка (также называемая «именем свойства»), а значение может быть чем угодно.

Мы можем представить объект в виде ящика с подписанными папками. Каждый элемент данных хранится в своей папке, на которой написан ключ. По ключу папку легко найти, удалить или добавить в неё что-либо.

Пустой объект («пустой ящик») можно создать, используя один из двух вариантов синтаксиса:

let user = new Object(); // синтаксис "конструктор объекта" let user = <>; // синтаксис "литерал объекта"

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

Литералы и свойства

При использовании литерального синтаксиса <. >мы сразу можем поместить в объект несколько свойств в виде пар «ключ: значение»:

let user = < // объект name: "John", // под ключом "name" хранится значение "John" age: 30 // под ключом "age" хранится значение 30 >;

У каждого свойства есть ключ (также называемый «имя» или «идентификатор»). После имени свойства следует двоеточие «:» , и затем указывается значение свойства. Если в объекте несколько свойств, то они перечисляются через запятую.

В объекте user сейчас находятся два свойства:

  1. Первое свойство с именем «name» и значением «John» .
  2. Второе свойство с именем «age» и значением 30 .

Можно сказать, что наш объект user – это ящик с двумя папками, подписанными «name» и «age».

Мы можем в любой момент добавить в него новые папки, удалить папки или прочитать содержимое любой папки.

Для обращения к свойствам используется запись «через точку»:

// получаем свойства объекта: alert( user.name ); // John alert( user.age ); // 30

Значение может быть любого типа. Давайте добавим свойство с логическим значением:

user.isAdmin = true;

Для удаления свойства мы можем использовать оператор delete :

delete user.age;

Имя свойства может состоять из нескольких слов, но тогда оно должно быть заключено в кавычки:

let user = < name: "John", age: 30, "likes birds": true // имя свойства из нескольких слов должно быть в кавычках >;

Последнее свойство объекта может заканчиваться запятой:

let user =

Это называется «висячая запятая». Такой подход упрощает добавление, удаление и перемещение свойств, так как все строки объекта становятся одинаковыми.

Объект, объявленный как константа, может быть изменён

Объект, объявленный через const , может быть изменён.

const user = < name: "John" >; user.name = "Pete"; // (*) alert(user.name); // Pete

Может показаться, что строка (*) должна вызвать ошибку, но нет, здесь всё в порядке. Дело в том, что объявление const защищает от изменений только саму переменную user , а не её содержимое.

Определение const выдаст ошибку только если мы присвоим переменной другое значение: user=. .

Есть ещё один способ сделать константами свойства объекта, который мы рассмотрим в главе Флаги и дескрипторы свойств.

Квадратные скобки

Для свойств, имена которых состоят из нескольких слов, доступ к значению «через точку» не работает:

// это вызовет синтаксическую ошибку user.likes birds = true

JavaScript видит, что мы обращаемся к свойству user.likes , а затем идёт непонятное слово birds . В итоге синтаксическая ошибка.

Точка требует, чтобы ключ был именован по правилам именования переменных. То есть не имел пробелов, не начинался с цифры и не содержал специальные символы, кроме $ и _ .

Для таких случаев существует альтернативный способ доступа к свойствам через квадратные скобки. Такой способ сработает с любым именем свойства:

let user = <>; // присваивание значения свойству user["likes birds"] = true; // получение значения свойства alert(user["likes birds"]); // true // удаление свойства delete user["likes birds"];

Сейчас всё в порядке. Обратите внимание, что строка в квадратных скобках заключена в кавычки (подойдёт любой тип кавычек).

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

let key = "likes birds"; // то же самое, что и user["likes birds"] = true; user[key] = true;

Здесь переменная key может быть вычислена во время выполнения кода или зависеть от пользовательского ввода. После этого мы используем её для доступа к свойству. Это даёт нам большую гибкость.

let user = < name: "John", age: 30 >; let key = prompt("Что вы хотите узнать о пользователе?", "name"); // доступ к свойству через переменную alert( user[key] ); // John (если ввели "name")

Запись «через точку» такого не позволяет:

let user = < name: "John", age: 30 >; let key = "name"; alert( user.key ); // undefined

Вычисляемые свойства

Мы можем использовать квадратные скобки в литеральной нотации для создания вычисляемого свойства.

let fruit = prompt("Какой фрукт купить?", "apple"); let bag = < [fruit]: 5, // имя свойства будет взято из переменной fruit >; alert( bag.apple ); // 5, если fruit="apple"

Смысл вычисляемого свойства прост: запись [fruit] означает, что имя свойства необходимо взять из переменной fruit .

И если посетитель введёт слово «apple» , то в объекте bag теперь будет лежать свойство .

По сути, пример выше работает так же, как и следующий пример:

let fruit = prompt("Какой фрукт купить?", "apple"); let bag = <>; // имя свойства будет взято из переменной fruit bag[fruit] = 5;

…Но первый пример выглядит лаконичнее.

Мы можем использовать и более сложные выражения в квадратных скобках:

let fruit = 'apple'; let bag = < [fruit + 'Computers']: 5 // bag.appleComputers = 5 >;

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

Подведём итог: в большинстве случаев, когда имена свойств известны и просты, используется запись через точку. Если же нам нужно что-то более сложное, то мы используем квадратные скобки.

Свойство из переменной

В реальном коде часто нам необходимо использовать существующие переменные как значения для свойств с тем же именем.

function makeUser(name, age) < return < name: name, age: age // . другие свойства >; > let user = makeUser("John", 30); alert(user.name); // John

В примере выше название свойств name и age совпадают с названиями переменных, которые мы подставляем в качестве значений этих свойств. Такой подход настолько распространён, что существуют специальные короткие свойства для упрощения этой записи.

Вместо name:name мы можем написать просто name :

function makeUser(name, age) < return < name, // то же самое, что и name: name age // то же самое, что и age: age // . >; >

Мы можем использовать как обычные свойства, так и короткие в одном и том же объекте:

let user = < name, // тоже самое, что и name:name age: 30 >;

Ограничения на имена свойств

Как мы уже знаем, имя переменной не может совпадать с зарезервированными словами, такими как «for», «let», «return» и т.д.

Но для свойств объекта такого ограничения нет:

// эти имена свойств допустимы let obj = < for: 1, let: 2, return: 3 >; alert( obj.for + obj.let + obj.return ); // 6

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

Все другие типы данных будут автоматически преобразованы к строке.

Например, если использовать число 0 в качестве ключа, то оно превратится в строку «0» :

let obj = < 0: "Тест" // то же самое что и "0": "Тест" >; // обе функции alert выведут одно и то же свойство (число 0 преобразуется в строку "0") alert( obj["0"] ); // Тест alert( obj[0] ); // Тест (то же свойство)

Есть небольшой подводный камень, связанный со специальным свойством __proto__ . Мы не можем установить его в необъектное значение:

let obj = <>; obj.__proto__ = 5; // присвоим число alert(obj.__proto__); // [object Object], значение - это объект, т.е. не то, что мы ожидали

Как мы видим, присвоение примитивного значения 5 игнорируется.

Мы более подробно исследуем особенности свойства __proto__ в следующих главах Прототипное наследование, а также предложим способы исправления такого поведения.

Проверка существования свойства, оператор «in»

В отличие от многих других языков, особенность JavaScript-объектов в том, что можно получить доступ к любому свойству. Даже если свойства не существует – ошибки не будет!

При обращении к свойству, которого нет, возвращается undefined . Это позволяет просто проверить существование свойства:

let user = <>; alert( user.noSuchProperty === undefined ); // true означает "свойства нет"

Также существует специальный оператор «in» для проверки существования свойства в объекте.

"key" in object

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *