#javascript
#javascript
Вопрос:
Я знаю, что Javascript всегда передает объекты по ссылке. Но как насчет других типов?
число — ?
строка — неизменяемая, поэтому это не должно иметь значения
object — ref
array — ?
функция — ?
регулярное выражение — ?
Я пришел к выводу, что не все значения в Javascript могут быть объектами и не могут передаваться по ссылке с помощью следующего кода:
function SomeFunc(func) {
var numba = 0;
var innerFunc = function() {
numba = func(numba);//try commenting me out and switching to next line
//func(numba);//numba fails to increment
return numba;
};
return innerFunc;
}
//this variable should persist the numba variable through closure. Incrementing each call by 1.
var closure = SomeFunc(function(numba) {
numba = numba 1;
return numba;
});
document.writeln(closure());
document.writeln(closure());
document.writeln(closure());
Потому numba
что не удается увеличить, если я не верну число и не обновлю переменную при закрытии…тогда это говорит мне, что это не передается по ссылке. Я что-то упускаю?
или возьмите самый простой
function UpdateNumber(numba) {
numba = 10;
document.writeln('in func number becomes ' numba);
}
var numba2 = 5;
UpdateNumber(numba2);
document.writeln('back to caller number is ' numba2);
//in func number becomes 10
//back to caller number is 5
Комментарии:
1. Я отправил электронное письмо Дугласу Крокфорду, и его ответ на эту ситуацию таков: «Когда вы присваиваете переменной, вы даете переменной ссылку. Когда вы передаете переменную в качестве аргумента, вы передаете ссылку, которую содержит переменная, а не саму переменную. » Я считаю, что проблема просто в том, что мне еще многому предстоит научиться.
Ответ №1:
Нет. JavaScript всегда передается по значению, а не по ссылке.
Люди часто путают возможность изменять объект в методе и делают так, чтобы модификация была видна снаружи как передаваемая по ссылке. Это не так. Передача по ссылке означает изменение того, на что указывает значение, видимое вне функции. Например
var f1 = function (p1) {
p1 = 42;
};
var x = {};
f1(x);
В этом примере, если JavaScript реализовал передачу по ссылке, тогда x === 42
было бы true. Однако это не так. Переменная x
все равно будет иметь значение {}
Комментарии:
1. «Объекты передаются по ссылке. Они никогда не копируются» — «Javascript: хорошие части» Дугласа Крокфорда
2. @П.Брайан. Mackey ссылки по-прежнему передаются по значению. Существует разница между «передачей по ссылке» и «передачей ссылки по значению». JavaScript выполняет последнее.
3. В JavaScript нет указателя, поэтому передача по ссылке приобретает другое значение…
4. @xavierm02 не совсем. Другие языки поддерживают понятие передачи по ссылке без необходимости указателей (C # без
unsafe
, F # и VB. Например, Net). Понятие передачи по ссылке можно рассматривать независимо от указателей. Это способ передачи местоположения вместо значения. C также может делать это вместо указателей.5. @xavierm02, не верь всему, что читаешь в книгах по JS ;). Если вам интересна тема, прочитайте эту статью: ECMA-262 подробно: стратегия оценки 1 Джареду.
Ответ №2:
Я думаю, что более продуктивно думать примерно так:
- Существуют изменяемые (объекты, массивы и т.д.) и неизменяемые (числа, логические значения, строки) значения.
- Передача параметров всегда осуществляется по назначению.
- Присвоение параметров невозможно увидеть вне функции, поскольку вы просто меняете локальную переменную, чтобы указать где-то в другом месте.
- Если объект является изменяемым, и вы вызываете методы или присваиваете свойства, эти изменения видны за пределами функции (т. Е. Объект не был скопирован, когда он был передан в функцию)
Поэтому вам не нужно узнавать, передается ли тип по ссылке, вам нужно проверить, является ли он изменяемым.
Ответ №3:
Каждый объект передается по ссылке. И на самом деле все является объектом.
function addProperty( o ) {
o.property = 'value';
}
// here, we can see that even numbers are passed by reference
var n = new Number( 1 );
addProperty( n );
console.log( n.property );// 'value'
Но даже если все передается по ссылке, для litterals вы можете считать, что они передаются по значению, потому что вы не можете их изменять.
var n = 1;
n.property = 'value';
console.log( n.property );// undefined
В ES 5 есть эта новая функция Object.freeze
, которая делает невозможным изменение объекта.
По сути, то, что вы делаете при передаче litteral, — это передача неизменяемого объекта.
var n = 1;
var o = Object.create( null );
Object.freeze( o );
doWhatTheFuckYouWant( o );
doWhatTheFuckYouWant( n );
В обоих случаях вы можете быть уверены, что функция ничего не изменит в вашем объекте, потому что в объекте ничего нельзя изменить. Поэтому вам просто все равно, клонировано оно или нет.