Основи
Ви можете цього не знати, але в JavaScript, коли ми взаємодіємо з рядковими, числовими або булевими примітивами, ми входимо в прихований світ об'єктних тіней і примусу.
рядок, число, булева, нульова, невизначена та символ.
В JavaScript існує 7 примітивних типів: undefined, null, boolean, string, number, bigintі symbol. Все інше - об’єкт. Примітивні типи boolean, stringі numberїх можна обернути своїми об'єктами. Ці об'єкти є екземплярами Boolean, Stringі Numberконструкторів відповідно.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
Якщо примітиви не мають властивостей, чому "this is a string".lengthповертає значення?
Тому що JavaScript буде легко примусовий між примітивами та об'єктами. У цьому випадку значення рядка примушується до об'єкта рядка для доступу до довжини властивості. Об'єкт струни використовується лише на частку секунди, після чого його приносять у жертву Богам зі збирання сміття - але, в дусі телевізійних відкриттів, ми захопимо невловиму істоту і збережемо її для подальшого аналізу ...
Щоб продемонструвати це далі, розглянемо наступний приклад, в якому ми додаємо нове властивість до прототипу конструктора String.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
Таким чином, примітиви мають доступ до всіх властивостей (включаючи методи), визначені їх відповідними конструкторами об'єктів.
Тому ми побачили, що примітивні типи при необхідності примусово примушуються до відповідного об'єкта.
Аналіз toString() методу
Розглянемо наступний код
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
Як було сказано вище, що насправді відбувається, коли ми називаємо toString()метод примітивного типу, він повинен бути примушений до його об'єктного аналога, перш ніж він може викликати метод.
тобто myNumber.toString()еквівалентноNumber.prototype.toString.call(myNumber) і аналогічно для інших примітивних типів.
Але що робити, якщо замість примітивного типу перейти в toString()метод відповідного аналога функції конструктора об'єктів, ми змусимо передати примітивний тип як параметр toString()методу конструктора функції об'єкта (Object.prototype.toString.call(x) )?
Пильніший погляд на Object.prototype.toString ()
Відповідно до документації , Коли викликається метод toString, виконуються наступні кроки:
- Якщо
thisзначення є undefined, поверніть"[object Undefined]" .
- Якщо
thisзначення є null, поверніть"[object Null]" .
- Якщо це значення не вказане вище, Нехай
Oбуде результатом виклику, який toObjectпередаєthis значення як аргументу.
- Нехай клас є значенням
[[Class]]внутрішньої властивості O.
- Повертає строкове значення , яке є результатом конкатенації трьох рядків
"[object ", classі "]".
Зрозумійте це з наступного прикладу
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
Посилання:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/ 2010/09/27 / таємне життя-примітивів JavaScript /