Переменные (объявление функции - это просто функция, хранящаяся в переменной) ищутся в цепочке областей (переходя к следующей внешней области, пока не будет найдена переменная с именем):
let a = 1; // outer scope
{ // inner scope
console.log(a); // looked up in "inner scope", than "outer scope"
}
Свойства объекта ищутся в цепочке прототипов объектов, поэтому, если вы выполните
a.b
, тогда a
будет просмотрено в областях, как объяснено выше, а затем к b
будет получен доступ к полученномуобъект (все является объектом в JavaScript, за исключением «ничего» (undefined
, null
)) путем поиска цепочки прототипов.Для простого объекта цепочка довольно короткая:
const a = { b: 1 }; // object -> Object.prototype
Здесь b
будет найдено в самом объекте.Однако все объекты наследуются от объекта Object.prototype
, поэтому, если вы добавите к этому свойство (пожалуйста, не надо):
Object.prototype.test = 1;
, вы сможете найти его на каждом объекте, так как поиск проходит вверхцепочка прототипов, и достигает Object.prototype
:
console.log({}.test); // 1
Теперь для чисел (как в вашем случае) они наследуют Number.prototype
, так что вы можете сделать:
Number.prototype.addMe = function() {
console.log(this);
};
// two dots are needed to distinguish it from numbers with a fraction (e.g. 1.2)
1..addMe();
Тосказал, что теперь addMe
можно вызывать на каждый номер, везде в вашем коде.Хотя это может показаться полезным, на самом деле это неприятно, поскольку вы не знаете, где был добавлен определенный метод
1..whereDoIComeFrom()
, который делает код нечитаемым и неструктурированным.Вместо этого, если вам нужна определенная функциональность несколько раз, абстрагируйте ее в функцию, не трогайте собственные прототипы.
Я предполагаю, что addMe
- это просто упрощенный пример, если это не так, читайте дальше:
Если вы передадите аргумент функции в JavaScript, значение будет скопировано (это немного сложнее с не примитивами (все, кроме чисел, логических значений и т. д.)) в переменную параметрафункции, названной так здесь:
function addMe(a){
a = a+1;
console.log(a); // 2
return a;
}
var num = 1;
addMe(num);
console.log(num); // 1 ... ?
вы фактически получили две переменные (a
и num
), изменение a
не изменит num
.Но когда вы возвращаете a
, вы можете сделать:
num = addMe(num);
, который копирует значение num
в a
, затем увеличивает a
на единицу и затем копирует значение a
обратнодо num
.