From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../global_objects/object/constructor/index.html | 237 +++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 files/uk/web/javascript/reference/global_objects/object/constructor/index.html (limited to 'files/uk/web/javascript/reference/global_objects/object/constructor') diff --git a/files/uk/web/javascript/reference/global_objects/object/constructor/index.html b/files/uk/web/javascript/reference/global_objects/object/constructor/index.html new file mode 100644 index 0000000000..ef2362cdec --- /dev/null +++ b/files/uk/web/javascript/reference/global_objects/object/constructor/index.html @@ -0,0 +1,237 @@ +--- +title: Object.prototype.constructor +slug: Web/JavaScript/Reference/Global_Objects/Object/constructor +tags: + - JavaScript + - Object + - Властивість + - прототип +translation_of: Web/JavaScript/Reference/Global_Objects/Object/constructor +--- +
{{JSRef}}
+ +

Повертає посилання на функцію-конструктор {{jsxref("Object", "об'єкта")}}, що створила екземпляр об'єкта. Зауважте, що значення цієї властивості є посиланням на саму функцію, а не рядком, що містить ім'я функції. Значення, доступне лише для читання, мають лише примітивні значення, як то 1true або "test".

+ +

Опис

+ +

Усі об'єкти (за виключенням об'єктів, створених через Object.create(null)) матимуть властивість constructor. Об'єкти, створені без явного використання функції-конструктора (тобто, об'єктними та масивними літералами), матимуть властивість constructor, що вказує на конструктор фундаментального об'єкта для цього об'єкта.

+ +
var o = {};
+o.constructor === Object; // true
+
+var o = new Object;
+o.constructor === Object; // true
+
+var a = [];
+a.constructor === Array; // true
+
+var a = new Array;
+a.constructor === Array; // true
+
+var n = new Number(3);
+n.constructor === Number; // true
+ +

Приклади

+ +

Відображення конструктора об'єкта

+ +

Наступний приклад створює конструктор Tree та об'єкт цього типу, theTree. Далі приклад демонструє властивість constructor об'єкта theTree.

+ +
function Tree(name) {
+  this.name = name;
+}
+
+var theTree = new Tree('Redwood');
+console.log('theTree.constructor дорівнює ' + theTree.constructor);
+
+ +

Цей приклад виведе наступний результат:

+ +
theTree.constructor дорівнює function Tree(name) {
+  this.name = name;
+}
+
+ +

Зміна конструктора об'єкта

+ +

Наступний приклад покаже як можна змінити конструктор загальних об'єктів. Тільки true, 1 та "test" не зміняться, оскілки їхні конструктори доступні лише для читання. Цей приклад демонструє, що не завжди безпечно покладатися на властивість об'єкта constructor.

+ +
function Type () {}
+
+var types = [
+  new Array(),
+  [],
+  new Boolean(),
+  true,             // лишається незмінним
+  new Date(),
+  new Error(),
+  new Function(),
+  function () {},
+  Math,
+  new Number(),
+  1,                // лишається незмінним
+  new Object(),
+  {},
+  new RegExp(),
+  /(?:)/,
+  new String(),
+  'test'            // лишається незмінним
+];
+
+for (var i = 0; i < types.length; i++) {
+  types[i].constructor = Type;
+  types[i] = [types[i].constructor, types[i] instanceof Type, types[i].toString()];
+}
+
+console.log(types.join('\n'));
+
+ +

Цей приклад виведе наступний результат (коментарі додані для довідки):

+ +
function Type() {},false,                                     // new Array()
+function Type() {},false,                                     // []
+function Type() {},false,false                                // new Boolean()
+function Boolean() {
+    [native code]
+},false,true                                                  // true
+function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600    // new Date()
+function Type() {},false,Error                                // new Error()
+function Type() {},false,function anonymous() {
+
+}                                                             // new Function()
+function Type() {},false,function () {}                       // function () {}
+function Type() {},false,[object Math]                        // Math
+function Type() {},false,0                                    // new Number()
+function Number() {
+    [native code]
+},false,1                                                     // 1
+function Type() {},false,[object Object]                      // new Object()
+function Type() {},false,[object Object]                      // {}
+function Type() {},false,/(?:)/                               // new Regexp()
+function Type() {},false,/(?:)/                               // /(?:)/
+function Type() {},false,                                     // new String()
+function String() {
+    [native code]
+},false,test
+ +

Зміна конструктора функції

+ +

Переважно ця властивість використовується для визначення функції як функції-конструктора з подальшим викликом її з оператором new та наслідуванням через ланцюжок прототипів.

+ +
function Parent() {}
+Parent.prototype.parentMethod = function parentMethod() {};
+
+function Child() {}
+Child.prototype = Object.create(Parent.prototype); // перевизначення дочірнього прототипу на прототип Parent
+
+Child.prototype.constructor = Child; // повернення початкового конструктора прототипу Child
+ +

Але коли нам потрібно виконувати цей останній рядок? Нажаль, відповідь - залежить від обставин.

+ +

Спробуємо визначити випадки, коли переприсвоєння початкового конструктора зіграє важливу роль, а коли воно стане додатковим непотрібним рядком коду.

+ +

Візьмемо наступний випадок: об'єкт має метод create для створення самого себе.

+ +
function Parent() {};
+function CreatedConstructor() {}
+
+CreatedConstructor.prototype = Object.create(Parent.prototype);
+
+CreatedConstructor.prototype.create = function create() {
+  return new this.constructor();
+}
+
+new CreatedConstructor().create().create(); // TypeError undefined is not a function, оскільки constructor === Parent
+ +

У наведеному вище прикладі виняток виникне тому, що конструктор посилається на Parent.

+ +

Щоб уникнути цього, просто призначте потрібний конструктор, який ви збираєтесь використовувати.

+ +
function Parent() {};
+function CreatedConstructor() {}
+
+CreatedConstructor.prototype = Object.create(Parent.prototype);
+CreatedConstructor.prototype.constructor = CreatedConstructor; // призначте конструктор, який будете використовувати
+
+CreatedConstructor.prototype.create = function create() {
+  return new this.constructor();
+}
+
+new CreatedConstructor().create().create(); // так непогано
+ +

Гаразд, тепер зрозуміло, чому зміна конструктора може бути досить корисною.

+ +

Розглянемо інший випадок.

+ +
function ParentWithStatic() {}
+
+ParentWithStatic.startPosition = { x: 0, y:0 };
+ParentWithStatic.getStartPosition = function getStartPosition() {
+  return this.startPosition;
+}
+
+function Child(x, y) {
+  this.position = {
+    x: x,
+    y: y
+  };
+}
+
+Child.prototype = Object.create(ParentWithStatic.prototype);
+Child.prototype.constructor = Child;
+
+Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() {
+  var position = this.position;
+  var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, оскільки конструктор - Child
+
+  return {
+    offsetX: startPosition.x - position.x,
+    offsetY: startPosition.y - position.y
+  }
+};
+ +

В цьому прикладі нам треба залишити батьківський конструктор, щоб все працювало як слід.

+ +

Висновок: ручна зміна або встановлення конструктора може призвести до різноманітних та іноді заплутаних наслідків. Щоб запобігти цьому, визначте роль конструктора у кожному конкретному випадку. В більшості випадків конструктор не використовується, і в перепризначенні немає необхідності.

+ +

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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецифікаціяСтатусКоментар
{{SpecName('ESDraft', '#sec-object.prototype.constructor', 'Object.prototype.constructor')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-object.prototype.constructor', 'Object.prototype.constructor')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-15.2.4.1', 'Object.prototype.constructor')}}{{Spec2('ES5.1')}}
{{SpecName('ES1')}}{{Spec2('ES1')}}Початкове визначення. Реалізоване у JavaScript 1.1.
+ +

Сумісність з веб-переглядачами

+ + + +

{{Compat("javascript.builtins.Object.constructor")}}

+ +
-- cgit v1.2.3-54-g00ecf