ÐÑедÑпÑеждение: Ðзменение пÑоÑоÑипа [[Prototype]]
обÑекÑа ÑвлÑеÑÑÑ, по Ñамой пÑиÑоде опÑимизаÑии доÑÑÑпа к ÑвойÑÑвам в ÑовÑеменнÑÑ
движкаÑ
JavaScript, оÑÐµÐ½Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾Ð¹ опеÑаÑией, ÑÑо ÑпÑаведливо Ð´Ð»Ñ Ð»Ñбого бÑаÑзеÑа и движка JavaScript. Ðзменение пÑоÑоÑипов оÑÐµÐ½Ñ Ñонко и обÑиÑно влиÑÐµÑ Ð½Ð° пÑоизводиÑелÑноÑÑÑ, пÑиÑÑм ÑÑо влиÑние не огÑаниÑиваеÑÑÑ Ð¿ÑоÑÑо вÑеменем Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑии пÑиÑÐ²Ð°Ð¸Ð²Ð°Ð½Ð¸Ñ obj.__proto__ = ...
, оно Ð¼Ð¾Ð¶ÐµÑ ÑаÑпÑоÑÑÑанÑÑÑÑÑ Ð½Ð° лÑбой код, коÑоÑÑй Ð¸Ð¼ÐµÐµÑ Ð´Ð¾ÑÑÑп к лÑÐ±Ð¾Ð¼Ñ Ð¾Ð±ÑекÑÑ, Ñей пÑоÑоÑип [[Prototype]]
бÑл изменÑн. ÐÑли Ð²Ñ Ð·Ð°Ð±Ð¾ÑиÑеÑÑ Ð¾ пÑоизводиÑелÑноÑÑи, Ð²Ñ Ð½Ð¸ÐºÐ¾Ð³Ð´Ð° не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑÑ Ð¿ÑоÑоÑип [[Prototype]]
обÑекÑа. ÐмеÑÑо ÑÑого ÑоздайÑе обÑÐµÐºÑ Ñ Ð½ÑжнÑм пÑоÑоÑипом [[Prototype]]
, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼ÐµÑода Object.create()
.
ÐÑедÑпÑеждение: ХоÑÑ Ð½Ð° ÑегоднÑÑний Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð±Ð¾Ð»ÑÑинÑÑво бÑаÑзеÑов поддеÑживаÑÑ ÑвойÑÑво Object.prototype.__proto__
, его поведение ÑолÑко недавно бÑло ÑÑандаÑÑизиÑовано в новой ÑпеÑиÑикаÑии ECMAScript 6. ÐÑли вам ÑÑебÑеÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑжка бÑаÑзеÑов до ÑÑой ÑпеÑиÑикаÑии, ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ Ð²Ð¼ÐµÑÑо него меÑод Object.getPrototypeOf()
.
СвойÑÑво __proto__
обÑекÑа Object.prototype
ÑвлÑеÑÑÑ ÑвойÑÑвом доÑÑÑпа (комбинаÑией геÑÑеÑа и ÑеÑÑеÑа), коÑоÑое ÑаÑÑиÑÑÐµÑ Ð²Ð½ÑÑÑенний пÑоÑоÑип [[Prototype]]
обÑекÑа (ÑвлÑÑÑийÑÑ Ð¾Ð±ÑекÑом или null
), ÑеÑез коÑоÑÑй оÑÑÑеÑÑвлÑлÑÑ Ð´Ð¾ÑÑÑп.
ÐÑполÑзование ÑвойÑÑва __proto__
вÑзÑÐ²Ð°ÐµÑ ÑпоÑÑ Ð¸ многиÑ
оно ÑазоÑаÑовало. Ранее оно никогда не вклÑÑалоÑÑ Ð² ÑпеÑиÑикаÑÐ¸Ñ EcmaScript, но ÑовÑеменнÑе бÑаÑзеÑÑ Ð²ÑÑ Ñавно ÑеÑили его ÑеализоваÑÑ. Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ ÑвойÑÑво __proto__
ÑÑандаÑÑизиÑовано в ÑпеÑиÑикаÑии ECMAScript 6 и бÑÐ´ÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑÑÑ Ð² бÑдÑÑем. Тем не менее, изменение пÑоÑоÑипа [[Prototype]]
обÑекÑа вÑÑ ÐµÑÑ Ð¾ÑÑаÑÑÑÑ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾Ð¹ опеÑаÑией, коÑоÑÑÑ ÑледÑÐµÑ Ð¸Ð·Ð±ÐµÐ³Ð°ÑÑ, еÑли Ð²Ñ Ð±ÐµÑпокоиÑеÑÑ Ð¾ пÑоизводиÑелÑноÑÑи.
СвойÑÑво __proto__
Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð¿Ñи опÑеделении лиÑеÑала обÑекÑа, ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°Ñ Ð¿ÑоÑоÑип [[Prototype]]
обÑекÑа пÑи его Ñоздании. ÐÑÐ¾Ñ ÑпоÑоб Ð¼Ð¾Ð¶ÐµÑ ÑаÑÑмаÑÑиваÑÑÑÑ ÐºÐ°Ðº алÑÑеÑнаÑива меÑÐ¾Ð´Ñ Object.create()
. СмоÑÑиÑе Ñакже лиÑеÑалÑнÑй ÑинÑакÑÐ¸Ñ Ð¸Ð½Ð¸ÑиализаÑии обÑекÑа.
var shape = {},
circle = new Circle();
// УÑÑановка пÑоÑоÑипа обÑекÑа
shape.__proto__ = circle;
// ÐолÑÑение пÑоÑоÑипа обÑекÑа
console.log(shape.__proto__ === circle); // true
ÐбÑаÑиÑе внимание: название ÑвойÑÑва ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· двÑÑ Ð¿Ð¾Ð´ÑÑÑкиваний, ÑледÑÑÑÐ¸Ñ Ð·Ð° ними пÑÑи Ñимволов «proto» и ÑледÑÑÑÐ¸Ñ Ð·Ð° ними еÑÑ Ð´Ð²ÑÑ Ð¿Ð¾Ð´ÑÑÑкиваний.
ÐпиÑаниеÐеÑÑÐµÑ ÑвойÑÑва __proto__
ÑаÑÑиÑÑÐµÑ Ð·Ð½Ð°Ñение внÑÑÑеннего пÑоÑоÑипа [[Prototype]]
обÑекÑа. ÐÐ»Ñ Ð¾Ð±ÑекÑов, ÑозданнÑÑ
Ñ Ð¸ÑполÑзованием лиÑеÑалÑной ÑоÑÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑекÑа, ÑÑо знаÑение Ñавно Object.prototype
. ÐÐ»Ñ ÑÑнкÑий ÑÑо знаÑение Ñавно Function.prototype
. ÐÐ»Ñ Ð¾Ð±ÑекÑов, ÑозданнÑÑ
Ñ Ð¸ÑполÑзованием ÑоÑÐ¼Ñ new fun
, где fun
ÑвлÑеÑÑÑ Ð¾Ð´Ð½Ð¾Ð¹ из вÑÑÑоеннÑÑ
ÑÑнкÑий-конÑÑÑÑкÑоÑов, пÑедоÑÑавлÑемÑÑ
JavaScript (Array
, Boolean
, Date
, Number
, Object
, String
и Ñак далее â вклÑÑÐ°Ñ Ð½Ð¾Ð²Ñе конÑÑÑÑкÑоÑÑ, добавленнÑе в пÑоÑеÑÑе ÑазвиÑÐ¸Ñ JavaScript), ÑÑо знаÑение Ñавно fun.prototype
. ÐÐ»Ñ Ð¾Ð±ÑекÑов, ÑозданнÑÑ
Ñ Ð¸ÑполÑзованием ÑоÑÐ¼Ñ new fun
, где fun
ÑвлÑеÑÑÑ ÑÑнкÑией, опÑеделÑнной в ÑкÑипÑе, ÑÑо знаÑение Ñавно знаÑÐµÐ½Ð¸Ñ fun.prototype
во вÑÐµÐ¼Ñ Ð²ÑÑиÑÐ»ÐµÐ½Ð¸Ñ new fun
. Ðменно поÑÑÐ¾Ð¼Ñ Ð¿Ñи пÑиÑваивании fun.prototype
нового знаÑениÑ, Ñанее ÑозданнÑе ÑкземплÑÑÑ fun
пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°Ñ Ð¸ÑполÑзоваÑÑ Ð¿ÑедÑдÑÑее знаÑение в каÑеÑÑве Ñвоего пÑоÑоÑипа [[Prototype]]
, а поÑледÑÑÑие вÑÐ·Ð¾Ð²Ñ new fun
бÑдÑÑ Ð¸ÑполÑзоваÑÑ Ð²Ð½Ð¾Ð²Ñ Ð¿ÑиÑвоенное знаÑение в каÑеÑÑве Ñвоего пÑоÑоÑипа [[Prototype]]
.
ÐеÑÑÐµÑ __proto__
позволÑÐµÑ Ð¿ÑоÑоÑÐ¸Ð¿Ñ [[Prototype]]
обÑекÑа бÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑемÑм. ÐбÑÐµÐºÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑаÑÑиÑÑемÑм в ÑооÑвеÑÑÑвии Ñ Object.isExtensible()
: еÑли ÑÑо не Ñак, вÑкидÑваеÑÑÑ Ð¸ÑклÑÑение TypeError
. ÐÑедоÑÑавлÑемое знаÑение должно бÑÑÑ Ð¾Ð±ÑекÑом или null
. ÐÑедоÑÑавление лÑбого дÑÑгого знаÑÐµÐ½Ð¸Ñ Ð½Ð¸Ñего не даÑÑ.
ÐÐ»Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸Ñ Ñого, как пÑоÑоÑÐ¸Ð¿Ñ Ð¸ÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð½Ð°ÑледованиÑ, ÑмоÑÑиÑе ÑÑаÑÑÑ ÑÑководÑÑва «ÐаÑледование и ÑепоÑки пÑоÑоÑипов».
СвойÑÑво __proto__
ÑвлÑеÑÑÑ Ð¿ÑоÑÑÑм ÑвойÑÑвом доÑÑÑпа на обÑекÑе Object.prototype
â ÑвойÑÑвом, ÑоÑÑоÑÑим из геÑÑеÑа и ÑеÑÑеÑа. СвойÑÑво __proto__
бÑÐ´ÐµÑ Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾, еÑли, в конеÑном иÑоге, его поиÑк пÑойдÑÑ ÑеÑез Object.prototype
, но пÑи доÑÑÑпе к Ð½ÐµÐ¼Ñ Ð½Ðµ ÑеÑез Object.prototype
, оно найдено не бÑдеÑ. ÐÑли пеÑед пÑоÑмоÑÑом Object.prototype
бÑден найдено какое-нибÑÐ´Ñ Ð´ÑÑгое ÑвойÑÑво __proto__
, оно ÑкÑÐ¾ÐµÑ Ð¸Ñкомое ÑвойÑÑво Object.prototype
.
var noProto = Object.create(null);
console.log(typeof noProto.__proto__); // undefined
console.log(Object.getPrototypeOf(noProto)); // null
noProto.__proto__ = 17;
console.log(noProto.__proto__); // 17
console.log(Object.getPrototypeOf(noProto)); // null
var protoHidden = {};
Object.defineProperty(protoHidden, "__proto__", {
value: 42,
writable: true,
configurable: true,
enumerable: true,
});
console.log(protoHidden.__proto__); // 42
console.log(Object.getPrototypeOf(protoHidden) === Object.prototype); // true
ÐÑимеÑÑ
Ð ÑледÑÑÑем пÑимеÑе ÑоздаÑÑÑÑ Ð½Ð¾Ð²Ñй ÑкземплÑÑ Employee
, а заÑем пÑовеÑÑеÑÑÑ, ÑÑо его ÑвойÑÑво __proto__
ÑвлÑеÑÑÑ Ñем же ÑамÑм обÑекÑом, ÑÑо и его конÑÑÑÑкÑÐ¾Ñ prototype
.
// ÐеклаÑиÑÑем ÑÑнкÑиÑ, иÑполÑзÑемÑÑ ÐºÐ°Ðº конÑÑÑÑкÑоÑ
function Employee() {
/* иниÑиализиÑÑем ÑкземплÑÑ */
}
// СоздаÑм новÑй ÑкземплÑÑ Employee
var fred = new Employee();
// ÐÑовеÑка на ÑквиваленÑноÑÑÑ
fred.__proto__ === Employee.prototype; // true
Ð ÑÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ fred
ÑнаÑледован Ð¾Ñ Employee
, однако пÑиÑваивание дÑÑгого обÑекÑа в fred.__proto__
Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ ÑÑо:
function Cow() {
/* иниÑиализиÑÑем ÑкземплÑÑ */
}
// ÐÑиÑваиваем __proto__ новÑй обÑекÑ
fred.__proto__ = Cow.prototype;
ТепеÑÑ fred
наÑледÑеÑÑÑ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвенно Ð¾Ñ Cow.prototype
, а не Ð¾Ñ Employee.prototype
, и ÑеÑÑÐµÑ ÑвойÑÑва, изнаÑалÑно ÑнаÑледованнÑе Ð¾Ñ Employee.prototype
.
Ðднако, ÑÑо пÑименÑеÑÑÑ ÑолÑко к ÑаÑÑиÑÑемÑм обÑекÑам, Ñ Ð½ÐµÑаÑÑиÑÑемÑÑ
обÑекÑов ÑвойÑÑво __proto__
не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾:
var obj = {};
Object.preventExtensions(obj);
obj.__proto__ = {}; // вÑÐºÐ¸Ð½ÐµÑ TypeError
ÐбÑаÑиÑе внимание, ÑÑо ÑвойÑÑво __proto__
Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÐµÑеопÑеделено даже Ñ Ð¾Ð±ÑекÑа Object.prototype
, еÑли Ð½Ð¾Ð²Ð°Ñ ÑепоÑка заканÑиваеÑÑÑ null
:
var b = {};
Object.prototype.__proto__ = Object.create(
null, // [[Prototype]]
{
hi: {
value: function () {
alert("hi");
},
},
},
);
b.hi();
ÐÑли ÑвойÑÑво __proto__
обÑекÑа Object.prototype
не ÑÑÑановлено в null
, или в дÑÑгой обÑекÑ, ÑÑÑ ÑепоÑка пÑоÑоÑипов, в конеÑном иÑоге, Ñвно не заканÑиваеÑÑÑ Ð·Ð½Ð°Ñением null
, бÑÐ´ÐµÑ Ð²ÑкинÑÑо иÑклÑÑение TypeError
«ÑиклиÑеÑкое знаÑение __proto__», поÑколÑÐºÑ ÑепоÑка должна заканÑиваÑÑÑÑ null
(как ÑÑо и пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð½Ð° Object.prototype
пÑи ноÑмалÑнÑÑ
обÑÑоÑÑелÑÑÑваÑ
).
ÐÑимеÑание: СпеÑиÑикаÑÐ¸Ñ ES6 ÑÑебÑÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶ÐºÑ ÑвойÑÑва __proto__
ÑолÑко в бÑаÑзеÑаÑ
и не ÑÑебÑÐµÑ ÐµÐ³Ð¾ поддеÑÐ¶ÐºÑ Ð² дÑÑгиÑ
окÑÑжениÑÑ
(Ñ
оÑÑ Ð¾Ð½Ð¾ и ÑекомендÑеÑÑÑ Ð² каÑеÑÑве обÑзаÑелÑного). ÐÑли Ð²Ð°Ñ ÐºÐ¾Ð´ должен ÑабоÑаÑÑ Ð² не-бÑаÑзеÑнÑÑ
окÑÑжениÑÑ
, вмеÑÑо ÑвойÑÑва ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ Ð¼ÐµÑÐ¾Ð´Ñ Object.getPrototypeOf()
и Object.setPrototypeOf()
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4