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])
Три символа.