Язык программирования javascript (JS) - это мультипарадигменный язык программирования. Обучающая статья посвящена языку программирования javascript (JS), хотя вернее будет сказать – описывает работу примитивов javascript. В материале рассматриваются основные принципы работы примитивных типов данных в javascript и, в дополнение, то, что происходит под прикрытием. С использованием методики принуждения примитивов к объектам был выполнен анализ работы JS Engine и свойств примитивов. Автором была изучена способность назначать свойства объектов перед их примитивными аналогами.
На основании полученных данных установлена способность назначать свойства - почти единственное преимущество объектов. Если javascript обнаруживает попытку назначить свойство примитиву, Js Engine приведет его к объекту. Но, этот новый объект не имеет ссылок и сразу станет кормом для сборки мусора. Хорошее понимание примитивов и того, что происходит «под капотом», является важным шагом на пути к более глубокому изучению языка.
Язык программирования javascript - примитивы javascript и их тайная жизнь
Предположу, что для вас будет в новинку факт того, что в JavaScript, взаимодействуя со строковыми, числовыми или логическими примитивами, вы попадаете в скрытый мир Зазеркалья.
Логические, числовые и строковые примитивы могут быть обернуты их объектными аналогами. Такие объекты станут экземплярами Boolean, String и Number конструкторов объектов соответственно.
Пример использование конструктора new:
typeof new Boolean(false); // return "object"
typeof (new Boolean(false)).valueOf(); // return "boolean"
typeof false; //"boolean"
typeof Boolean(false); // return "boolean"
typeof new String("word"); // return "object"
typeof (new String("word ")).valueOf(); // return "string"
typeof " word "; // return "string"
typeof String("word "); // return "string"
typeof 321; // return "number"
typeof Number(321); //return "number"
typeof new Number(431); // return "object"
typeof (new Number(431)).valueOf(); // return "number"
Если примитивы не имеют свойств, почему «string» .length возвращает значение?
a; //"cba"
typeof a; //" return string" (still a primitive)
b; //"cba"
typeof b; // return "object"
Идем дальше. Как и во всех значимых работах, мы выворачивали наизнанку устоявшееся положение дел, не позволяя объекту собирать мусор, пока присутствует b.
(! В строгом режиме неуловимое существо устраняется)
Безусловно, существуют варианты проверить тип объекта, не затрагивая сборку мусора:
(123).toString(); // return “object"
Здесь можно отметить однозначный факт – примитивы имеют доступ ко всем свойствам (включая методы), определенным соответствующими конструкторами объектов.
JavaScript и valueOf
В JavaScript, valueOf и toString являются дочерними методами, перешедшими по наследству каждому объекту. Один из этих методов будет вызываться всякий раз, когда выражение встречает сложный объект, где ожидалось примитивное значение. Например:
alert(myCat);
let result = 2 + myCat;
Подведем черту. Если выражение намекает на необходимость строки, вызывается toString, в противном случае – valueOf. Если один из методов возвращает не примитив, шанс получает другой. В примерах выше ожидается, что myCat будет и строкой, и числом, поэтому они будут оцениваться как:
alert(myCat.toString()); //интерпретатор ожидал строку
let result = 2 + myCat.valueOf(); //ожидал число
[См. ECMA 5 главу 8.12.8 для полного алгоритма. Помните, что [[DefaultValue]], hint и ToPrimitive являются внутренними конструкциями]
Основываясь на этих правилах, вполне логично, что valueOf будет возвращать не строковое представление объекта.
Существует возможность воспользоваться значением valueOf для создания сжатого синтаксиса текущей даты, выраженной в миллисекундах:
(new Date()).valueOf(); //1588962243724 (date in ms)
+ new Date();//15889622488
+ 95(ожидается нестроковый примитив после знака+)
+new Date; //1588962256511 (то же самое, но даже более короткий синтаксис)
Если есть необходимость накатывать собственные показатели профилирования, можно воспользоваться информацией, представленной далее.
Большинство других реализаций valueOf по умолчанию не интересны:
Boolean(true).valueOf(); //true
Number('123').valueOf(); //123
"aaa".valueOf(); //"aaa"
Но ведь куда интереснее определить свои собственные значения реализаций, не так ли?
var toDollarRate = {
rubles: 0.014,
pounds: 1.5
}
var Drink = function(name, cost, currency) {
this.name = name;
this.cost = cost;
this.currency = currency;
}
Drink.prototype.costInDollars = function() {
return this.cost * (toDollarRate[this.currency] || 1);
}
var boddingtons = new Drink("Boddingtons", 2.50, 'pounds');
var peroni = new Drink("Peroni", 3.50, 'rubles');
var anchorSteam = new Drink("Anchor Steam", 3.50, 'dollars');
Drink.prototype.valueOf = Drink.prototype.costInDollars;
'$' + (boddingtons + peroni + anchorSteam).toFixed(2); //$7.30
Теоретически, приводя объект в логическое значение, он может представлять запрос, потенциально заканчивающийся как положительным, так и отрицательным результатом.
var SystemRequest = function(name) {
this.name = name;
}
SystemRequest.prototype.run = function() {
//симуляция результатов теста
this.success = Math.random(1)>0.5;
return this;
}
SystemRequest.prototype.valueOf = function() {
return this.success;
}
var request1 = new SystemRequest('request1');
var request2 = new SystemRequest('request2');
var request3 = new SystemRequest('request3');
request1.run() + request2.run() + request3.run(); //2
request1.run() + request2.run() + request3.run(); //1
request1.run() + request2.run() + request3.run(); //3 (all passed!)
Здесь valueOf возвращает логическое значение, но в инструкциях окончательного выполнения используется конкатенация для преобразования логических значений в числа (1 для передачи, 0 для отказа).
Неплохим подспорьем может служить переопределение valueOf. И совершенно не имеет значения, использовать его так, или нет, знание того, как и почему JavaScript выбирает методы по умолчанию toString и valueOf, поможет вам лучше узнать код.
Язык программирования javascript - могут ли эти объекты быть приведены к значениям?
Вполне. Объекты этого типа являются не более чем обертками, их значение – примитив, который они обертывают, и чаще всего приводят к этому значению по мере необходимости.
//объект приведен к примитиву
var Twelve = new Number(12);
var fifteen = Twelve + 3;
fifteen; //15
typeof fifteen; //"number" (примитиву)
typeof Twelve; //"object"; (все еще объект)
//другой объект приведен к примитиву
new String("salli") + "slet"; //" sallister"
//объект не приведен (потому что оператор typeof может работать с объектами)
typeof new String("salli ") + " slet "; //"object slet "
Увы, Boolean объекты приводятся не так легко. И, чтобы провернуть нож в ране, Boolean объект оценивается как true, если его значение не равно null или undefined. Можно воспользоваться:
if (new Boolean(true)) {
alert("false???");
}
Чаще всего имеет смысл явно запрашивать логические объекты для их значения. Следующее поможет определить, является значение «truthy» или «falsey»….
var empty = "";
new Boolean(empty).valueOf(); //false
... но на практике легче сделать так...
var empty = Boolean("");
empty; //false
... или даже так ...
var empty = "";
!!empty; //false
Язык программирования javascript - позволяет ли принуждение присваивать значения примитивам?
Нет
const monthNum = "october ";
primitive.monthNum = 11;
primitive.monthNum; //undefined;
Если JavaScript обнаруживает попытку назначить свойство примитиву, он действительно приведет к примитиву объекта. Но, как и в предыдущих примерах, этот новый объект не имеет ссылок и сразу пойдет в сборщик мусора.
Вот псевдокодовое представление того же примера, чтобы
проиллюстрировать, что на самом деле происходитconst primitive = "october";
primitive.monthNum = 11;
// новый объект, созданный для установки свойства(new String("october ")). monthNum = 11;
primitive.monthNum;
// еще один новый объект, созданный для получения свойства(new String("october")).monthNum; //undefined
Заметим, все это не только бесполезно, но и довольно иррационально.
В результате
Оказывается, что способность назначать свойства - почти единственное преимущество объектов перед их примитивными аналогами. Строки, логические значения и числа имеют конкретные и четко определенные цели.
Тем не менее хорошее понимание примитивов и того, что происходит “под капотом” когда вы взаимодействуете с ними, является важным шагом на пути к более глубокому изучению языка.
#джава #самоучитель java #примитивы java #java #java для новичков #javascript #java для чайников #java script #обучение java
Источник: https://pclegko.ru/programmirovanie/jazyk-programmirovanija-javascript.html