Вопрос к программистам

Ошибка в книге или я туплю? Помогите разобраться пожалуйста.

Изучаю сейчас книгу Дэвида Флэнагана по javascript. Там такой пример (коменты из книги):


"Этот прием часто используется в функциях для определения значений по умолчанию параметров:


// Скопировать свойства объекта o в объект p и вернуть p

function copy(o, p) {

p = p | | { } ; // Если объект p не был передан, создать новый объект

}"


Разве не так должно быть? :

function copy(o, p) {

p = o | | { } ; // Если объект p не был передан, создать новый объект

}"

1
Автор поста оценил этот комментарий

моя ошибка, должно быть

function copy(o) {

return o | | { } ; // Если объект p не был передан, создать новый объект

}

и

var b;

b = copy(a);


происходит такая фигня потому-что при передаче объекта в аргумент, он передается как pass-by-reference, т.е. ссылкой на объект и если мы внутри функции эту ссылку меняем объект вылетает из контекста


например

function test(a,b){

a = {val:1};

b.val = 1;

}

a = {val:0};

b = {val:0};

test(a,b);

a тут равен {val:0}, т.к. мы сбили референс внутри функции и новый референс работал только в контексте той функции и не попал в scope вызова (инкапсуляция)

b тут равен {val:1}, т.к. мы обратились к объекту по его ссылке и изменили значение внутри объекта, а значение ссылки при этом не трогали


както так, если не очень усложнять

раскрыть ветку (1)
Автор поста оценил этот комментарий
да, щас заработало. Вроде бы понял )
1
Автор поста оценил этот комментарий

не, в моем примере присвоит пустой объект только если p совсем не передали

вот так:

copy(100)

А в твоем присваивание пустого объекта будет допольнительно в тех случаях, когда p равно "", 0 или false

раскрыть ветку (1)
Автор поста оценил этот комментарий
понял. Спасибо
1
Автор поста оценил этот комментарий

В es6 уже можно писать

function copy(o, p={}) {

и не беспокоиться.

Но сам шаблон все равно стоит знать, так еще многие пишут

Причем есть отличие: если в p передали false, 0 или "", то описанный ТС шаблон заменит ее значение на {}, а если указать как я пишу - то не заменит

раскрыть ветку (1)
Автор поста оценил этот комментарий
т.е. в твоем примере независимо от того, будет ли параметр p содержать что-то или нет, функция всё ровно присвоит p пустой объект?
показать ответы
1
Автор поста оценил этот комментарий

Тут тебе объясняют как использовать аргумент p, если он не определен. Так что все верно. А вот вместе с комментом это вызывает тупо когнитивный диссонанс.

p равен p , елси он true, т.е че-то есть(предполагается, что не пустой объект), иначе p равен пустому объекту!

раскрыть ветку (1)
Автор поста оценил этот комментарий
ясно. Спасибо! А то я что-то заплутал )
2
Автор поста оценил этот комментарий

P.S.

в твоем примере как раз ошибка

а ошибка в том, что речь о функции копирования...

она сработает если o это нативный объект вроде String Number Boolean и иже с ними...

а вот если ты передашь первым аргументом объект с типом Object,

то вместо копирования ты получишь ссылку на объект


вот пример

var a = {val:0};

function copy(o, p) {

p = o | | { } ; // Если объект p не был передан, создать новый объект

}

var b;

copy(a,b);

console.log(a); // тут мы увидим {val:0}

console.log(b); // и тут мы увидим {val:0}

//а теперь изменим "a"

a.val = 1;

console.log(a); // тут мы увидим {val:1}

console.log(b); // и опа тут тоже {val:1}


чтобы такого не происходило, нам нужно в функции копирования создавать новый пустой объект и рекурсивно копировать в него свойства и методы объекта донора

раскрыть ветку (1)
Автор поста оценил этот комментарий
Спасибо большое, что помогли разобраться! Я затестил этот пример и выходит, что b undefined везде. Почему так?
показать ответы