основы
Вы можете этого не знать, но в 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]".
- Если это значение не является ни одним из вышеперечисленных, Let
Oбудет результатом вызова с toObjectпередачей thisзначения в качестве аргумента.
- Пусть class будет значением
[[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-примитивы /