Return True

12. Ouroborobj

function ouroborobj(x) {
  return x in x;
}

Название отсылает к уроборосу — змею, кусающему себя за хвост.

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

И вот поскольку in нужно «передать» имя ключа, скорее всего тут всё дело в том, как приводятся типы при выполнении этой операции. В спецификации про это сказано, что левый операнд сперва приводится к строке, а только потом используется в вычислении. (На деле там всё сложнее, но даже этого знания нам уже достаточно.)

Получается, что нам нужно найти такой объект, который при приведении к строке превратится в своё же свойство. В третьей задаче мы уже затрагивали приведение объектов к строке, и заметили тогда, что от обычных объектов в этом случае пользы не очень много, они просто превращаются в "[object Object]". А вот массив превращается в строку, в которой перечисляются все его элементы.

Раскручивая эту цепочку дальше, получаем, что нам нужен какой-то такой массив, который бы при приведении к строке превратился в свойство, которое бы нашлось в этом массиве. Так, у массивов есть свойство length, а потому:

ouroborobj(['length'])

А это уже решение в 10 символов.

Но если посмотрим на ключи этого массива, то увидим, что у него есть ещё и свойство 0, что вполне себе ожидаемо:

> Reflect.ownKeys(['length'])
["0", "length"]

А раз так, более короткое решение напрашивается само собой:

ouroborobj([0])

Три символа.