2015-10-17 6 views
3

У меня есть быстрый вопрос о какой-то код, который я не понимаю:Javascript Вызов По ссылке

var anonymousGreet = function(){ 
    console.log('Hi'); 
} 

function log(a){ 
    console.log(a); 
} 

log(anonymousGreet); 

В коде выше, когда я звоню журнал функции и передать в функции выражения anonymousGreet в качестве параметра для входа. Означает ли это, что переменная «a» в журнале указывает на переменную anonymous greet, которая затем указывает на объект функции. Или непосредственно указывает объект функции, на который указывает anonymousGreet? Я немного запутался, если первый указывает на переменную анонимного приветствия или он непосредственно указывает на объект функции, на который указывает anonymousGreet. Извините, если это сбивает с толку, но любая помощь будет оценена! Спасибо вам!

ответ

4

Если вы приехали из C++ фона, то простая рационализация

  • В JavaScript все передается по значению, ссылки никогда не используются
  • Все передаваемые значения однако указатели к объектам

Например, когда вы пишете:

a = b + c; 

вы должны представить себе (в C++) что-то вдоль линий

Object *a, *b, *c; 
a = new Number(b->numericValue() + c->numericValue()); 

(обратите внимание, что, однако Javascript отличается от C++ обеспечивает сборщик мусора, нет явный delete).

Это, конечно, простое описание того, что является наблюдаемым поведением (и это может быть реализация самых первых движков Javascript). Сегодня то, что действительно происходит за кулисами, намного сложнее и включает в себя создание машинного кода (JIT).

Это причина, по которой, например:

function foo(x) { 
    x[0] = 1; 
} 

var a = [0]; 
foo(a); // Will change the content of a[0] 

но

function bar(x) { 
    x = 9; 
} 

var b = 0; 
bar(b); // Will *NOT* change the content of b 
+0

Это определенно прояснилось. Я прихожу из C++ и C background haha ​​... но теперь все ясно! Спасибо! –

+0

Большое вам спасибо за этот подробный ответ! У меня есть еще один быстрый вопрос: скажем, у нас есть две переменные: var greet = 'Hi' и var greet = 'Hola' (я намеренно сделал имена переменных одинаковыми). Первое приветствие указывает на примитив «Hi», а затем указывает на примитив «Hola», Когда указатель переменной приветствия обновляется до point to 'Hola' делает предыдущий указатель, указывающий на «Привет», освобождается или значение исходного указателя просто изменяется, чтобы указать на «Hola»? –

+0

@NorthernStar: у вас может быть много указателей (переменных), указывающих на один и тот же объект, освобождение произойдет, когда последний указатель переназначается на что-то еще. Обратите внимание, что Javascript не предоставляет «деструкторов» или «слабых указателей», поэтому вы не можете быть проинформированы о том, когда объект будет освобожден. Более того, «строки» в Javascript неизменяемы и для неизменных значений нет способа узнать, ссылаются ли два указателя на один и тот же объект или нет (например, нет способа узнать адрес объекта или что-то вроде Python 'id (x) ', вы можете получить доступ только к значению). – 6502

2

Да, если вы проверите === anonymousGreet, результат будет правдой. Все примитивные значения передаются по значению, но объекты передаются по ссылке в Javascript.

var anonymousGreet = function(){ 
 
    console.log('Hi'); 
 
} 
 

 
function log(a){ 
 
    console.log(a === anonymousGreet); //true 
 
    console.log(a); 
 
} 
 

 
log(anonymousGreet);

+0

ааа хорошо, что имеет смысл! Спасибо так много! –

2

По сути терминологии, и, чтобы избежать путаницы, я бы избежать использования слова «указатель» , Слишком легко запутаться при использовании слова «указатель». Иногда «A, указывающий на B» может означать, что A является своего рода псевдонимом для B. Или что B можно изменить через A. Или A может указывать на B, который указывает на C; что это значит?

ИМО это понятнее использовать терминологию, что в JavaScript переменная имеет значение. Вот и все. Он имеет значение. Он не указывает ни на что, он не ссылается ни на что, он имеет значение.

Однако две переменные могут занимать один и тот же значение , такие как пустой массив []:

var a = []; 
var b = a; 

Оба a и b провести такое же значение, определенный пустой массив. Мы видим, что они имеют одинаковое значение, проверив a === b. Поскольку они имеют одинаковое значение, это значение можно манипулировать с помощью одного; a.push(1) и b.push(1) делают то же самое, потому что они одновременно манипулируют значением, общим для каждого. Повторное присвоение a просто изменяет значение, которое имеет значение a; он не влияет и не может повлиять на b, и наоборот. b не является «указателем» на a или псевдоним a; это переменная, которая имеет то же значение, что и a.

Другими словами, a = b делает не сделать a "точку" в b. Он также не копирует значение b и присваивает его a. Он дает a значение от b, так что a и b теперь имеют идентичное значение.

Механизм передачи параметров функции можно рассматривать как определенный тип назначения. Это делает формальный параметр в определении функции предполагать или удерживать значение параметра, указанного в вызове. Когда я определить функцию

function foo(x) { console.log(x); } 

, а затем вызвать его

var y = 42; 
foo(y); 

переменная/параметр x присваивается значение параметра, переданного в вызове функции. Другими словами, x имеет значение y. x не «указывает» на y, и это не копия y. Оно имеет такое же значение как y, которое в этом случае равно 42.

Давайте ваш конкретный пример:

var anonymousGreet = function(){ 
    console.log('Hi'); 
} 

function log(a){ 
    console.log(a); 
} 

log(anonymousGreet); 

В этом случае anonymousGreet является переменной, которая, в силу уступки, имеет в качестве своего значения конкретной анонимной функции. Когда вы вызываете log(anonymousGreet), параметр a в функцию log установлен для удержания значения параметра в вызове, поэтому теперь он имеет значение anonymousGreet. Он не «указывает» на переменную anonymousGreet, и любые ее изменения не могут повлиять на значение anonymousGreet и, конечно же, функцию, которую представляет это значение.

Означает ли, что в журнале переменная a указывает на переменную anonymousGreet, которая затем, указывая на объект функции?

Нет, это означает, что переменная/параметр a в журнале содержит значениепроводится по anonymousGreet, которая является анонимной функцией.

Или a указывает непосредственно на объект функции, на который указывает anonymousGreet?

Да, но не «указывают на вещи, адресуемый параметром», а скорее «имеет значение anonymousGreet, который содержит в качестве значения анонимную функцию.

+0

Здравствуйте, @torazaburo, большое вам спасибо за подробный ответ. Я все еще немного смущен, так как я думал, что примитивы в JS передаются по значению, а объекты передаются по ссылке. Так технически, когда я передаю anonymousGreet функции журнала, параметр «a» в функции журнала просто будет содержать одно и то же значение anonymousGreet (это анонимная функция)? Но если я делаю a.someProperty = 'Hello', который изменил исходный объект функции, который переменная anonymousGreet держала правильно? –

Смежные вопросы