Мои два цента ... Я так понимаю. (Не стесняйтесь поправлять меня, если я ошибаюсь)
Пора выбросить все, что вы знаете о передаче по значению / ссылке.
Потому что в JavaScript не имеет значения, передается ли он по значению, по ссылке или как-то еще. Важно то, что изменение или присвоение параметров, переданных в функцию.
Хорошо, позвольте мне изо всех сил объяснить, что я имею в виду. Допустим, у вас есть несколько объектов.
var object1 = {};
var object2 = {};
Что мы сделали, так это присвоение ... Мы присвоили 2 отдельных пустых объекта переменным object1 и object2.
Теперь предположим, что нам больше нравится object1 ... Итак, мы назначаем новую переменную.
var favoriteObject = object1;
Затем по какой-то причине мы решаем, что объект 2 нам больше нравится. Итак, мы делаем небольшое перераспределение.
favoriteObject = object2;
Ничего не произошло ни с object1, ни с object2. Мы вообще не меняли никаких данных. Все, что мы сделали, это переназначили наш любимый объект. Важно знать, что object2 и favouriteObject назначены одному и тому же объекту. Мы можем изменить этот объект с помощью любой из этих переменных.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
Хорошо, теперь давайте посмотрим, например, на примитивы, такие как строки
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Опять же, выбираем фаворита.
var favoriteString = string1;
Обе переменные favouriteString и string1 присвоены «Hello world». А что, если мы хотим изменить нашу любимую строку ??? Что случится???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Ой .... Что случилось. Мы не могли изменить string1, изменив favouriteString ... Почему ?? Потому что мы не изменили нашу строку object. Все, что мы сделали, - это ПОВТОРИТЬ НАЗНАЧЕНИЕ переменной любимойString новой строки. Это по сути отключило его от string1. В предыдущем примере, когда мы переименовали наш объект, мы ничего не назначали. (Ну, не самой переменной, ... мы, однако, присвоили свойство name новой строке.) Вместо этого мы изменили объект, который поддерживает связи между двумя переменными и лежащие в основе объекты. (Даже если бы мы хотели изменить или мутировать строковый объект сам, мы не смогли бы этого сделать, потому что строки фактически неизменяемы в JavaScript.)
Теперь перейдем к функциям и передаче параметров ... Когда вы вызываете функцию и передаете параметр, то, по сути, вы выполняете присвоение новой переменной, и она работает точно так же, как если бы вы присвоили ей равный ( =) знак.
Возьмите эти примеры.
var myString = 'hello';
// Assign to a new variable (just like when you pass to a function)
var param1 = myString;
param1 = 'world'; // Re assignment
console.log(myString); // Logs 'hello'
console.log(param1); // Logs 'world'
Теперь то же самое, но с функцией
function myFunc(param1) {
param1 = 'world';
console.log(param1); // Logs 'world'
}
var myString = 'hello';
// Calls myFunc and assigns param1 to myString just like param1 = myString
myFunc(myString);
console.log(myString); // logs 'hello'
Хорошо, а теперь давайте приведем несколько примеров с использованием объектов ... во-первых, без функции.
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Assign to a new variable (just like when you pass to a function)
var otherObj = myObject;
// Let's mutate our object
otherObj.firstName = 'Sue'; // I guess Joe decided to be a girl
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Sue'
// Now, let's reassign the variable
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object has no influence on the other
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Jack';
Теперь то же самое, но с вызовом функции
function myFunc(otherObj) {
// Let's mutate our object
otherObj.firstName = 'Sue';
console.log(otherObj.firstName); // Logs 'Sue'
// Now let's re-assign
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
console.log(otherObj.firstName); // Logs 'Jack'
// Again, otherObj and myObject are assigned to 2 very different objects
// And mutating one object doesn't magically mutate the other
}
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject
myFunc(myObject);
console.log(myObject.firstName); // Logs 'Sue', just like before
Хорошо, если вы прочитаете весь этот пост, возможно, теперь вы лучше понимаете, как вызовы функций работают в JavaScript. Не имеет значения, передается что-то по ссылке или по значению ... Важно то, что присваивание или мутация.
Каждый раз, когда вы передаете переменную функции, вы назначаете любое имя переменной параметра, как если бы вы использовали знак равенства (=).
Всегда помните, что знак равенства (=) означает присвоение. Всегда помните, что передача параметра функции в JavaScript также означает присвоение. Они одинаковы, и две переменные связаны точно таким же образом (то есть, это не так, если вы не считаете, что они назначены одному и тому же объекту).
Единственный раз, когда изменение переменной влияет на другую переменную, - это когда изменяется базовый объект (в этом случае вы изменили не переменную, а сам объект.
Нет смысла проводить различие между объектами и примитивами, потому что это работает точно так же, как если бы у вас не было функции и вы просто использовали знак равенства для присвоения новой переменной.
Единственная проблема - это когда имя переменной, которую вы передаете в функцию, совпадает с именем параметра функции. Когда это происходит, вы должны относиться к параметру внутри функции, как если бы это была совершенно новая переменная, приватная для функции (потому что это так).
function myFunc(myString) {
// myString is private and does not affect the outer variable
myString = 'hello';
}
var myString = 'test';
myString = myString; // Does nothing, myString is still 'test';
myFunc(myString);
console.log(myString); // Logs 'test'
person
Ray Perea
schedule
04.08.2014
object.create
- единственный механизм, который клонирует объект в Javascript (см. stackoverflow.com/q/728360/2155068 ). - person MjrKusanagi   schedule 13.03.2015Object.create
можно считать правильной техникой клонирования, т.е. если вы измените исходную копию объекта, это повлияет на клон, только изменения клона не повлияют на исходный объект. Конечно, он имеет свое применение, и JavaScript разработан вокруг этой концепции (прототипное наследование), но я думаю, что называтьObject.create
единственным механизмом клонирования объекта - это заблуждение. - person Danail Nachev   schedule 10.11.2015var x=3, y=x; f(x); alert(y === x);
, тогда функцияf()
может создавать отчет о предупрежденияхfalse
, а неtrue
. В JavaScript это невозможно, поэтому это не передача по ссылке. Хорошо, что можно передавать ссылки на изменяемые объекты, но это не то, что означает передача по ссылке. Как я уже сказал, жаль, что терминология такая запутанная. - person Pointy   schedule 16.12.2015ref
и делая различие дляout
. - person Ry-♦   schedule 12.12.2019