РпеÑвой главе ÑÑого Ñаздела Ð¼Ñ Ñпоминали, ÑÑо ÑÑÑеÑÑвÑÑÑ ÑовÑеменнÑе меÑÐ¾Ð´Ñ ÑабоÑÑ Ñ Ð¿ÑоÑоÑипами.
СвойÑÑво __proto__ ÑÑиÑаеÑÑÑ ÑÑÑаÑевÑим, и по ÑÑандаÑÑÑ Ð¾Ð½Ð¾ должно поддеÑживаÑÑÑÑ ÑолÑко бÑаÑзеÑами.
СовÑеменнÑе же меÑÐ¾Ð´Ñ ÑÑо:
- Object.create(proto[, descriptors]) â ÑоздаÑÑ Ð¿ÑÑÑой обÑÐµÐºÑ Ñо ÑвойÑÑвом
[[Prototype]], ÑказаннÑм какproto, и необÑзаÑелÑнÑми деÑкÑипÑоÑами ÑвойÑÑвdescriptors. - Object.getPrototypeOf(obj) â возвÑаÑÐ°ÐµÑ ÑвойÑÑво
[[Prototype]]обÑекÑаobj. - Object.setPrototypeOf(obj, proto) â ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑвойÑÑво
[[Prototype]]обÑекÑаobjкакproto.
ÐÑи меÑÐ¾Ð´Ñ Ð½Ñжно иÑполÑзоваÑÑ Ð²Ð¼ÐµÑÑо __proto__.
ÐапÑимеÑ:
let animal = {
eats: true
};
// ÑоздаÑм новÑй обÑÐµÐºÑ Ñ Ð¿ÑоÑоÑипом animal
let rabbit = Object.create(animal);
alert(rabbit.eats); // true
alert(Object.getPrototypeOf(rabbit) === animal); // полÑÑаем пÑоÑоÑип обÑекÑа rabbit
Object.setPrototypeOf(rabbit, {}); // заменÑем пÑоÑоÑип обÑекÑа rabbit на {}
У Object.create еÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑй вÑоÑой аÑгÑменÑ: деÑкÑипÑоÑÑ ÑвойÑÑв. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ добавиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑное ÑвойÑÑво Ð½Ð¾Ð²Ð¾Ð¼Ñ Ð¾Ð±ÑекÑÑ Ñаким обÑазом:
let animal = {
eats: true
};
let rabbit = Object.create(animal, {
jumps: {
value: true
}
});
alert(rabbit.jumps); // true
ФоÑÐ¼Ð°Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð´ÐµÑкÑипÑоÑов опиÑан в главе Флаги и деÑкÑипÑоÑÑ ÑвойÑÑв.
ÐÑ Ñакже можем иÑполÑзоваÑÑ Object.create Ð´Ð»Ñ Â«Ð¿ÑодвинÑÑого» клониÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±ÑекÑа, более моÑного, Ñем копиÑование ÑвойÑÑв в Ñикле for..in:
// клон obj c Ñем же пÑоÑоÑипом (Ñ Ð¿Ð¾Ð²ÐµÑÑ
ноÑÑнÑм копиÑованием ÑвойÑÑв)
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
Такой вÑзов ÑоздаÑÑ ÑоÑнÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ð¾Ð±ÑекÑа obj, вклÑÑÐ°Ñ Ð²Ñе ÑвойÑÑва: пеÑеÑиÑлÑемÑе и непеÑеÑиÑлÑемÑе, геÑÑеÑÑ/ÑеÑÑеÑÑ Ð´Ð»Ñ ÑвойÑÑв â и вÑÑ ÑÑо Ñ Ð¿ÑавилÑнÑм ÑвойÑÑвом [[Prototype]].
ÐÑаÑÐºÐ°Ñ Ð¸ÑÑоÑиÑ
ÐÑли пеÑеÑÑиÑаÑÑ Ð²Ñе ÑпоÑÐ¾Ð±Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑоÑоÑипом, Ñо Ð¸Ñ Ð±ÑÐ´ÐµÑ Ð¼Ð½Ð¾Ð³Ð¾! Рмногие из Ð½Ð¸Ñ Ð´ÐµÐ»Ð°ÑÑ Ð¾Ð´Ð½Ð¾ и Ñо же!
ÐоÑÐµÐ¼Ñ Ñак?
Ð ÑÐ¸Ð»Ñ Ð¸ÑÑоÑиÑеÑÐºÐ¸Ñ Ð¿ÑиÑин.
- СвойÑÑво
"prototype"ÑÑнкÑии-конÑÑÑÑкÑоÑа ÑÑÑеÑÑвÑÐµÑ Ñ ÑовÑем Ð´Ð°Ð²Ð½Ð¸Ñ Ð²ÑемÑн. - Ðозднее, в 2012 годÑ, в ÑÑандаÑÑе поÑвилÑÑ Ð¼ÐµÑод
Object.create. ÐÑо давало возможноÑÑÑ ÑоздаваÑÑ Ð¾Ð±ÑекÑÑ Ñ ÑказаннÑм пÑоÑоÑипом, но не позволÑло ÑÑÑанавливаÑÑ/полÑÑаÑÑ ÐµÐ³Ð¾. Тогда бÑаÑзеÑÑ Ñеализовали неÑÑандаÑÑнÑй акÑеÑÑоÑ__proto__, коÑоÑÑй позволил ÑÑÑанавливаÑÑ/полÑÑаÑÑ Ð¿ÑоÑоÑип в лÑбое вÑемÑ. - Ðозднее, в 2015 годÑ, в ÑÑандаÑÑ Ð±Ñли добавленÑ
Object.setPrototypeOfиObject.getPrototypeOf,заменÑÑÑие Ñобой акÑеÑÑоÑ__proto__, коÑоÑÑй ÑпоминаеÑÑÑ Ð² ÐÑиложении Ð ÑÑандаÑÑа, коÑоÑое не обÑзаÑелÑно к поддеÑжке в небÑаÑзеÑнÑÑ Ð¾ÐºÑÑжениÑÑ . ÐÑи ÑÑом де-ÑакÑо__proto__вÑÑ ÐµÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаеÑÑÑ Ð²ÐµÐ·Ð´Ðµ.
РиÑоге ÑейÑÐ°Ñ Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð²Ñе ÑÑи ÑпоÑÐ¾Ð±Ñ Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¿ÑоÑоÑипом.
ÐоÑÐµÐ¼Ñ Ð¶Ðµ __proto__ бÑл заменÑн на ÑÑнкÑии getPrototypeOf/setPrototypeOf? ЧиÑайÑе далее, ÑÑÐ¾Ð±Ñ ÑзнаÑÑ Ð¾ÑвеÑ.
[[Prototype]] ÑÑÑеÑÑвÑÑÑиÑ
обÑекÑов, еÑли важна ÑкоÑоÑÑÑТеÑ
ниÑеÑки Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑÑÑановиÑÑ/полÑÑиÑÑ [[Prototype]] в лÑбое вÑемÑ. Ðо обÑÑно Ð¼Ñ ÑÑÑанавливаем пÑоÑоÑип ÑолÑко Ñаз во вÑÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑекÑа, а поÑле не менÑем: rabbit наÑледÑÐµÑ Ð¾Ñ animal, и ÑÑо не измениÑÑÑ.
Ð JavaScript движки Ñ
оÑоÑо опÑимизиÑÐ¾Ð²Ð°Ð½Ñ Ð´Ð»Ñ ÑÑого. Ðзменение пÑоÑоÑипа «на леÑÑ» Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Object.setPrototypeOf или obj.__proto__= â оÑÐµÐ½Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ, коÑоÑÐ°Ñ Ð»Ð¾Ð¼Ð°ÐµÑ Ð²Ð½ÑÑÑенние опÑимизаÑии Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑий доÑÑÑпа к ÑвойÑÑвам обÑекÑа. Так ÑÑо лÑÑÑе избегайÑе ÑÑого кÑоме ÑеÑ
ÑлÑÑаев, когда Ð²Ñ Ð·Ð½Ð°ÐµÑе, ÑÑо делаеÑе, или же когда ÑкоÑоÑÑÑ JavaScript Ð´Ð»Ñ Ð²Ð°Ñ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð³Ð¾ знаÑениÑ.
"ÐÑоÑÑейÑий" обÑекÑ
Ðак Ð¼Ñ Ð·Ð½Ð°ÐµÐ¼, обÑекÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÐºÐ°Ðº аÑÑоÑиаÑивнÑе маÑÑÐ¸Ð²Ñ Ð´Ð»Ñ Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ ÐºÐ»ÑÑ/знаÑение.
â¦Ðо еÑли Ð¼Ñ Ð¿Ð¾Ð¿ÑобÑем Ñ
ÑаниÑÑ ÑозданнÑе полÑзоваÑелÑми клÑÑи (напÑимеÑ, ÑловаÑи Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑким вводом), Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ замеÑиÑÑ Ð¸Ð½ÑеÑеÑнÑй Ñбой: вÑе клÑÑи ÑабоÑаÑÑ ÐºÐ°Ðº ожидаеÑÑÑ, за иÑклÑÑением "__proto__".
ÐоÑмоÑÑиÑе на пÑимеÑ:
let obj = {};
let key = prompt("What's the key?", "__proto__");
obj[key] = "some value";
alert(obj[key]); // [object Object], не "some value"!
ÐÑли полÑзоваÑÐµÐ»Ñ Ð²Ð²ÐµÐ´ÑÑ __proto__, пÑиÑвоение пÑоигноÑиÑÑеÑÑÑ!
Ð ÑÑо не должно ÑдивлÑÑÑ Ð½Ð°Ñ. СвойÑÑво __proto__ оÑобенное: оно должно бÑÑÑ Ð»Ð¸Ð±Ð¾ обÑекÑом, либо null, а ÑÑÑока не Ð¼Ð¾Ð¶ÐµÑ ÑÑаÑÑ Ð¿ÑоÑоÑипом.
Ðо Ð¼Ñ Ð½Ðµ намеÑевалиÑÑ ÑеализовÑваÑÑ Ñакое поведение, не Ñак ли? ÐÑ Ñ
оÑим Ñ
ÑаниÑÑ Ð¿Ð°ÑÑ ÐºÐ»ÑÑ/знаÑение, и клÑÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ "__proto__" не бÑл ÑоÑ
ÑанÑн надлежаÑим обÑазом. Так ÑÑо ÑÑо оÑибка!
ÐонкÑеÑно в ÑÑом пÑимеÑе поÑледÑÑÐ²Ð¸Ñ Ð½Ðµ Ñак ÑжаÑнÑ, но еÑли Ð¼Ñ Ð¿ÑиÑваиваем обÑекÑнÑе знаÑениÑ, Ñо пÑоÑоÑип и в Ñамом деле Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½Ñн. Ð ÑезÑлÑÑаÑе далÑнейÑее вÑполнение пойдÑÑ ÑовеÑÑенно непÑедÑказÑемÑм обÑазом.
ЧÑо Ñ Ñже вÑего â ÑазÑабоÑÑики не задÑмÑваÑÑÑÑ Ð¾ Ñакой возможноÑÑи ÑовÑем. ÐÑо Ð´ÐµÐ»Ð°ÐµÑ Ñакие оÑибки ÑложнÑм Ð´Ð»Ñ Ð¾ÑÐ»Ð°Ð²Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ даже пÑевÑаÑÐ°ÐµÑ Ð¸Ñ Ð² ÑÑзвимоÑÑи, оÑобенно когда JavaScript иÑполÑзÑеÑÑÑ Ð½Ð° ÑеÑвеÑе.
ÐеожиданнÑе веÑи могÑÑ ÑлÑÑаÑÑÑÑ Ñакже пÑи пÑиÑвоении ÑвойÑÑва toString, коÑоÑое по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑнкÑиÑ, и дÑÑгиÑ
ÑвойÑÑв, коÑоÑÑе Ñоже на Ñамом деле ÑвлÑÑÑÑÑ Ð²ÑÑÑоеннÑми меÑодами.
Ðак же избежаÑÑ Ð¿ÑоблемÑ?
Ðо-пеÑвÑÑ
, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пеÑеклÑÑиÑÑÑÑ Ð½Ð° иÑполÑзование коллекÑии Map, и Ñогда вÑÑ Ð±ÑÐ´ÐµÑ Ð² поÑÑдке.
Ðо и Object Ð¼Ð¾Ð¶ÐµÑ Ñакже Ñ
оÑоÑо подойÑи, поÑÐ¾Ð¼Ñ ÑÑо ÑоздаÑели ÑзÑка Ñже давно пÑодÑмали ÑеÑение пÑоблемÑ.
СвойÑÑво __proto__ â не обÑÑное, а акÑеÑÑоÑ, заданнÑй в Object.prototype:
Так ÑÑо пÑи ÑÑении или ÑÑÑановке obj.__proto__ вÑзÑваеÑÑÑ ÑооÑвеÑÑÑвÑÑÑий геÑÑеÑ/ÑеÑÑÐµÑ Ð¸Ð· пÑоÑоÑипа obj, и именно он ÑÑÑанавливаеÑ/полÑÑÐ°ÐµÑ ÑвойÑÑво [[Prototype]].
Ðак бÑло Ñказано в наÑале ÑÑой ÑекÑии ÑÑебника, __proto__ â ÑÑо ÑпоÑоб доÑÑÑпа к ÑвойÑÑÐ²Ñ [[Prototype]], ÑÑо не Ñамо ÑвойÑÑво [[Prototype]].
ТепеÑÑ, еÑли Ð¼Ñ Ñ Ð¾Ñим иÑполÑзоваÑÑ Ð¾Ð±ÑÐµÐºÑ ÐºÐ°Ðº аÑÑоÑиаÑивнÑй маÑÑив, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑделаÑÑ ÑÑо Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑого ÑÑÑка:
let obj = Object.create(null);
let key = prompt("What's the key?", "__proto__");
obj[key] = "some value";
alert(obj[key]); // "some value"
Object.create(null) ÑоздаÑÑ Ð¿ÑÑÑой обÑÐµÐºÑ Ð±ÐµÐ· пÑоÑоÑипа ([[Prototype]] бÑÐ´ÐµÑ null):
Таким обÑазом не бÑÐ´ÐµÑ ÑнаÑледованного геÑÑеÑа/ÑеÑÑеÑа Ð´Ð»Ñ __proto__. ТепеÑÑ ÑÑо ÑвойÑÑво обÑабаÑÑваеÑÑÑ ÐºÐ°Ðº обÑÑное ÑвойÑÑво, и пÑиведÑннÑй вÑÑе пÑÐ¸Ð¼ÐµÑ ÑабоÑÐ°ÐµÑ Ð¿ÑавилÑно.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ назваÑÑ Ñакой обÑÐµÐºÑ Â«Ð¿ÑоÑÑейÑим» или «ÑиÑÑÑм ÑловаÑнÑм обÑекÑом», поÑÐ¾Ð¼Ñ ÑÑо он еÑÑ Ð¿ÑоÑе, Ñем обÑÑнÑе обÑекÑÑ {...}.
ÐедоÑÑаÑок в Ñом, ÑÑо Ñ ÑакиÑ
обÑекÑов не бÑÐ´ÐµÑ Ð²ÑÑÑоеннÑÑ
меÑодов обÑекÑа, ÑакиÑ
как toString:
let obj = Object.create(null);
alert(obj); // ÐÑибка (no toString)
â¦Ðо обÑÑно ÑÑо ноÑмалÑно Ð´Ð»Ñ Ð°ÑÑоÑиаÑивнÑÑ Ð¼Ð°ÑÑивов.
ÐбÑаÑиÑе внимание, ÑÑо болÑÑинÑÑво меÑодов, ÑвÑзаннÑÑ
Ñ Ð¾Ð±ÑекÑами, имеÑÑ Ð²Ð¸Ð´ Object.something(...). РпÑимеÑÑ, Object.keys(obj). ÐодобнÑе меÑÐ¾Ð´Ñ Ð½Ðµ наÑ
одÑÑÑÑ Ð² пÑоÑоÑипе, Ñак ÑÑо они пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°Ñ ÑабоÑаÑÑ Ð´Ð»Ñ ÑакиÑ
обÑекÑов:
let chineseDictionary = Object.create(null);
chineseDictionary.hello = "ä½ å¥½";
chineseDictionary.bye = "åè§";
alert(Object.keys(chineseDictionary)); // hello,bye
ÐÑого
СовÑеменнÑе ÑпоÑÐ¾Ð±Ñ ÑÑÑановки и пÑÑмого доÑÑÑпа к пÑоÑоÑÐ¸Ð¿Ñ ÑÑо:
- Object.create(proto[, descriptors]) â ÑоздаÑÑ Ð¿ÑÑÑой обÑÐµÐºÑ Ñо ÑвойÑÑвом
[[Prototype]], ÑказаннÑм какproto(Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑnull), и необÑзаÑелÑнÑми деÑкÑипÑоÑами ÑвойÑÑв. - Object.getPrototypeOf(obj) â возвÑаÑÐ°ÐµÑ ÑвойÑÑво
[[Prototype]]обÑекÑаobj(Ñо же Ñамое, ÑÑо и геÑÑеÑ__proto__). - Object.setPrototypeOf(obj, proto) â ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑвойÑÑво
[[Prototype]]обÑекÑаobjкакproto(Ñо же Ñамое, ÑÑо и ÑеÑÑеÑ__proto__).
ÐÑÑÑоеннÑй геÑÑеÑ/ÑеÑÑÐµÑ __proto__ не безопаÑен, еÑли Ð¼Ñ Ñ
оÑим иÑполÑзоваÑÑ ÑозданнÑе полÑзоваÑелÑми клÑÑи в обÑекÑе. Ðак минимÑм поÑомÑ, ÑÑо полÑзоваÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²Ð²ÐµÑÑи "__proto__" как клÑÑ, Ð¾Ñ Ñего Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð¾Ñибка. ÐÑли повезÑÑ â поÑледÑÑÐ²Ð¸Ñ Ð±ÑдÑÑ Ð»Ñгкими, но, вообÑе говоÑÑ, они непÑедÑказÑемÑ.
Так ÑÑо Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ Ð»Ð¸Ð±Ð¾ Object.create(null) Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Â«Ð¿ÑоÑÑейÑего» обÑекÑа, либо иÑполÑзоваÑÑ ÐºÐ¾Ð»Ð»ÐµÐºÑÐ¸Ñ Map.
ÐÑоме ÑÑого, Object.create даÑÑ Ð½Ð°Ð¼ лÑгкий ÑпоÑоб ÑоздаÑÑ Ð¿Ð¾Ð²ÐµÑÑ
ноÑÑнÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ð¾Ð±ÑекÑа Ñо вÑеми деÑкÑипÑоÑами:
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
ÐÑ Ñакже ÑÑно Ñвидели, ÑÑо __proto__ â ÑÑо геÑÑеÑ/ÑеÑÑÐµÑ Ð´Ð»Ñ ÑвойÑÑва [[Prototype]], и наÑ
одиÑÑÑ Ð¾Ð½ в Object.prototype, как и дÑÑгие меÑодÑ.
ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ ÑоздаваÑÑ Ð¾Ð±ÑекÑÑ Ð±ÐµÐ· пÑоÑоÑипов Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Object.create(null). Такие обÑекÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÐºÐ°Ðº «ÑиÑÑÑе ÑловаÑи», Ñ Ð½Ð¸Ñ
Ð½ÐµÑ Ð¿Ñоблем Ñ Ð¸ÑполÑзованием ÑÑÑоки "__proto__" в каÑеÑÑве клÑÑа.
ÐÑÑ Ð¼ÐµÑодÑ:
- Object.keys(obj) / Object.values(obj) / Object.entries(obj) â возвÑаÑаÑÑ Ð¼Ð°ÑÑив вÑÐµÑ Ð¿ÐµÑеÑиÑлÑемÑÑ ÑобÑÑвеннÑÑ ÑÑÑоковÑÑ ÐºÐ»ÑÑей/знаÑений/Ð¿Ð°Ñ ÐºÐ»ÑÑ-знаÑение.
- Object.getOwnPropertySymbols(obj) â возвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив вÑÐµÑ ÑобÑÑвеннÑÑ ÑимволÑнÑÑ ÐºÐ»ÑÑей.
- Object.getOwnPropertyNames(obj) â возвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив вÑÐµÑ ÑобÑÑвеннÑÑ ÑÑÑоковÑÑ ÐºÐ»ÑÑей.
- Reflect.ownKeys(obj) â возвÑаÑÐ°ÐµÑ Ð¼Ð°ÑÑив вÑÐµÑ ÑобÑÑвеннÑÑ ÐºÐ»ÑÑей.
- obj.hasOwnProperty(key): возвÑаÑаеÑ
true, еÑли ÑobjеÑÑÑ ÑобÑÑвенное (не ÑнаÑледованное) ÑвойÑÑво Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼key.
ÐÑе меÑодÑ, коÑоÑÑе возвÑаÑаÑÑ ÑвойÑÑва обÑекÑов (Ñакие как Object.keys и дÑÑгие), возвÑаÑаÑÑ Â«ÑобÑÑвеннÑе» ÑвойÑÑва. ÐÑли Ð¼Ñ Ñ
оÑим полÑÑиÑÑ Ð¸ ÑнаÑледованнÑе, можно воÑполÑзоваÑÑÑÑ Ñиклом for..in.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)