una - variable por valor javascript




¿Es JavaScript un lenguaje de paso por referencia o de paso por valor? (20)

compartiendo lo que sé de referencias en javascript

En Javascript, los objetos se almacenan como referencias:

var a = {
  a: 1,
  b: 2,
  c: 3
};
var b = a;

//b.c is referencing to a.c value
console.log(b.c) //output: 3
//changing value of b.c
b.c = 4
//also changes the value of a.c
console.log(a.c) //output: 4

Los tipos primitivos (Número, Cadena, etc.) se pasan por valor, pero los Objetos son desconocidos, ya que pueden pasarse por valor (en caso de que consideremos que una variable que contiene un objeto es de hecho una referencia al objeto ) y pasado por referencia (cuando consideramos que la variable del objeto contiene el objeto en sí).

Aunque realmente no importa al final, quiero saber cuál es la forma correcta de presentar los argumentos pasando las convenciones. ¿Hay un extracto de la especificación de JavaScript, que define lo que debería ser la semántica con respecto a esto?


JavaScript pasa tipos primitivos por valor y tipos de objeto por referencia

Ahora, a la gente le gusta discutir sin parar sobre si "pasar por referencia" es la forma correcta de describir lo que Java et al. en realidad hacer El punto es este:

  1. Pasar un objeto no copia el objeto.
  2. Un objeto pasado a una función puede tener sus miembros modificados por la función.
  3. Un valor primitivo pasado a una función no puede ser modificado por la función. Se hace una copia.

En mi libro que se llama pasar por referencia.

- Brian Bi - ¿Qué lenguajes de programación se pasan por referencia?


  1. Tipo de variable primitiva como cadena, el número siempre se pasa como pase por valor.
  2. La matriz y el objeto se pasan como paso por referencia o se pasan por valor en función de estas dos condiciones.

    • Si está cambiando el valor de ese objeto o matriz con un nuevo objeto o matriz, entonces se pasa por valor.

      object1 = {item: "car"}; array1=[1,2,3];

    Aquí está asignando un nuevo objeto o matriz a uno antiguo. No está cambiando el valor de la propiedad del objeto antiguo. Por lo tanto, se pasa por valor.

    • Si está cambiando el valor de una propiedad de un objeto o matriz, se pasa por Referencia.

      object1.key1= "car"; array1[0]=9;

    Aquí está cambiando un valor de propiedad del objeto antiguo. No está asignando un nuevo objeto o matriz a uno antiguo. Por lo tanto, se pasa por referencia.

Código

    function passVar(object1, object2, number1) {

        object1.key1= "laptop";
        object2 = {
            key2: "computer"
        };
        number1 = number1 + 1;
    }

    var object1 = {
        key1: "car"
    };
    var object2 = {
        key2: "bike"
    };
    var number1 = 10;

    passVar(object1, object2, number1);
    console.log(object1.key1);
    console.log(object2.key2);
    console.log(number1);

Output: -
    laptop
    bike
    10

Considera lo siguiente:

  1. Las variables son punteros a valores en memoria.
  2. La reasignación de una variable simplemente apunta ese puntero a un nuevo valor.
  3. Reasignar una variable nunca afectará otras variables que apuntaban al mismo objeto

Entonces, olvídate de "pasar por referencia / valor" , no te cuelgues de "pasar por referencia / valor" porque:

  1. Los términos solo se usan para describir el comportamiento de un lenguaje, no necesariamente la implementación subyacente real. Como resultado de esta abstracción, los detalles críticos que son esenciales para una explicación decente se pierden, lo que inevitablemente conduce a la situación actual en la que un solo término no describe adecuadamente el comportamiento real y se debe proporcionar información adicional.
  2. Estos conceptos no se definieron originalmente con la intención de describir javascript en particular, por lo que no me siento obligado a usarlos cuando solo aumentan la confusión.

Para responder a tu pregunta: se pasan los punteros.


// code
var obj = {
    name: 'Fred',
    num: 1
};

// illustration
               'Fred'
              /
             /
(obj) ---- {}
             \
              \
               1


// code
obj.name = 'George';


// illustration
                 'Fred'


(obj) ---- {} ----- 'George'
             \
              \
               1


// code
obj = {};

// illustration
                 'Fred'


(obj)      {} ----- 'George'
  |          \
  |           \
 { }            1


// code
var obj = {
    text: 'Hello world!'
};

/* function parameters get their own pointer to 
 * the arguments that are passed in, just like any other variable */
someFunc(obj);


// illustration
(caller scope)        (someFunc scope)
           \             /
            \           /
             \         /
              \       /
               \     /
                 { }
                  |
                  |
                  |
            'Hello world'

Algunos comentarios finales:

  • Es tentador pensar que las primitivas se aplican mediante reglas especiales mientras que los objetos no lo son, pero las primitivas son simplemente el final de la cadena de punteros.
  • Como ejemplo final, considere por qué un intento común de borrar una matriz no funciona como se esperaba.


var a = [1,2];
var b = a;

a = [];
console.log(b); // [1,2]
// doesn't work because `b` is still pointing at the original array

En este capítulo del libro "JavaScript: la guía definitiva", encontrará una explicación muy detallada sobre cómo copiar, pasar y comparar por valor y por referencia.

Antes de dejar el tema de la manipulación de objetos y matrices por referencia, debemos aclarar un punto de nomenclatura. La frase "pasar por referencia" puede tener varios significados. Para algunos lectores, la frase se refiere a una técnica de invocación de función que permite que una función asigne nuevos valores a sus argumentos y tenga esos valores modificados visibles fuera de la función. Esta no es la forma en que se usa el término en este libro. Aquí, queremos decir simplemente que una referencia a un objeto o matriz, no el objeto en sí, se pasa a una función. Una función puede usar la referencia para modificar las propiedades del objeto o elementos de la matriz. Pero si la función sobrescribe la referencia con una referencia a un nuevo objeto o matriz, esa modificación no es visible fuera de la función. Los lectores familiarizados con el otro significado de este término pueden preferir decir que los objetos y las matrices se pasan por valor, pero el valor que se pasa es en realidad una referencia en lugar del objeto en sí.

Una cosa que todavía no puedo entender. Compruebe el código a continuación. ¿Alguna idea?

function A() {}
A.prototype.foo = function() {
    return 'initial value';
}


function B() {}
B.prototype.bar = A.prototype.foo;

console.log(A.prototype.foo()); //initial value
console.log(B.prototype.bar()); //initial value

A.prototype.foo = function() {
    return 'changed now';
}

console.log(A.prototype.foo()); //changed now
console.log(B.prototype.bar()); //Why still 'initial value'???

En JavaScript, el tipo de valor solo controla si ese valor se asignará mediante copia de valor o copia de referencia .

Los valores primitivos siempre se asignan / pasan por copia de valor :

  • null
  • undefined
  • cuerda
  • número
  • booleano
  • símbolo en ES6

Los valores compuestos siempre se asignan / pasan por referencia-copia

  • objetos
  • matrices
  • función

Por ejemplo

var a = 2;
var b = a; // `b` is always a copy of the value in `a`
b++;
a; // 2
b; // 3

var c = [1,2,3];
var d = c; // `d` is a reference to the shared `[1,2,3]` value
d.push( 4 );
c; // [1,2,3,4]
d; // [1,2,3,4]

En el fragmento de código anterior, porque 2 es una primitiva escalar, a contiene una copia inicial de ese valor, b se asigna otra copia del valor. Al cambiar b , de ninguna manera está cambiando el valor en a .

Pero tanto c como d son referencias separadas al mismo valor compartido [1,2,3] , que es un valor compuesto. Es importante tener en cuenta que ni c ni d más "poseen" el valor [1,2,3] ; ambos son solo referencias iguales al valor. Por lo tanto, al usar cualquiera de las dos referencias para modificar ( .push(4) ) el valor real de la array compartida, afecta solo al valor compartido, y ambas referencias harán referencia al valor recientemente modificado [1,2,3,4] .

var a = [1,2,3];
var b = a;
a; // [1,2,3]
b; // [1,2,3]

// later
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]

Cuando hacemos la asignación b = [4,5,6] , no estamos haciendo absolutamente nada para afectar a donde a todavía se hace referencia ( [1,2,3] ). Para hacer eso, b tendría que ser un puntero a una referencia en lugar de una referencia a la array , ¡pero no existe tal capacidad en JS!

function foo(x) {
    x.push( 4 );
    x; // [1,2,3,4]

    // later
    x = [4,5,6];
    x.push( 7 );
    x; // [4,5,6,7]
}

var a = [1,2,3];

foo( a );

a; // [1,2,3,4]  not  [4,5,6,7]

Cuando pasamos el argumento a , asigna una copia de a referencia a x . x y a son referencias separadas que apuntan al mismo valor [1,2,3] . Ahora, dentro de la función, podemos usar esa referencia para mutar el valor en sí ( push(4) ). Pero cuando hacemos la asignación x = [4,5,6] , esto no afecta de ninguna manera a dónde está apuntando la referencia inicial a - todavía apunta al valor (ahora modificado) [1,2,3,4] .

Para pasar efectivamente un valor compuesto (como una array ) por copia de valor, necesita hacer una copia manualmente, para que la referencia pasada no apunte al original. Por ejemplo:

foo( a.slice() );

Valor compuesto (objeto, matriz, etc.) que se puede pasar por copia de referencia

function foo(wrapper) {
    wrapper.a = 42;
}

var obj = {
    a: 2
};

foo( obj );

obj.a; // 42

Aquí, obj actúa como un envoltorio para la propiedad primitiva escalar a . Cuando se pasa a foo(..) , se pasa una copia de la referencia obj y se establece en el parámetro de wrapper . Ahora podemos usar la referencia del wrapper para acceder al objeto compartido y actualizar su propiedad. Una vez que finalice la función, obj.a verá el valor actualizado 42 .

Source


Javascript siempre se pasa por valor , todo es de tipo valor. Los objetos son valores, las funciones miembro de los objetos son valores en sí mismos (recuerde que las funciones son objetos de primera clase en Javascript). Además, con respecto al concepto de que todo en Javascript es un objeto , esto está mal. Cadenas, símbolos, números, valores booleanos, nulos e indefinidos son primitivos . En ocasiones, pueden aprovechar algunas de las funciones y propiedades de los miembros heredadas de sus prototipos básicos, pero esto es solo por conveniencia, no significa que sean objetos en sí mismos. Prueba lo siguiente para referencia

x = "test";
alert(x.foo);
x.foo = 12;
alert(x.foo);

En ambas alertas encontrará que el valor no está definido.


La variable no "mantiene" el objeto, tiene una referencia. Puede asignar esa referencia a otra variable, ahora ambas hacen referencia al mismo objeto. Siempre se pasa por valor (incluso cuando ese valor es una referencia ...).

No hay manera de alterar el valor mantenido por una variable pasada como parámetro, lo que sería posible si JS admitiera el paso por referencia.


Pasar argumentos a una función en JavaScript es análogo a pasar parámetros por valor de puntero en C:

/*
The following C program demonstrates how arguments
to JavaScript functions are passed in a way analogous
to pass-by-pointer-value in C. The original JavaScript
test case by @Shog9 follows with the translation of
the code into C. This should make things clear to
those transitioning from C to JavaScript.

function changeStuff(num, obj1, obj2)
{
    num = num * 10;
    obj1.item = "changed";
    obj2 = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);
console.log(obj1.item);    
console.log(obj2.item);

This produces the output:

10
changed
unchanged
*/

#include <stdio.h>
#include <stdlib.h>

struct obj {
    char *item;
};

void changeStuff(int *num, struct obj *obj1, struct obj *obj2)
{
    // make pointer point to a new memory location
    // holding the new integer value
    int *old_num = num;
    num = malloc(sizeof(int));
    *num = *old_num * 10;
    // make property of structure pointed to by pointer
    // point to the new value
    obj1->item = "changed";
    // make pointer point to a new memory location
    // holding the new structure value
    obj2 = malloc(sizeof(struct obj));
    obj2->item = "changed";
    free(num); // end of scope
    free(obj2); // end of scope
}

int num = 10;
struct obj obj1 = { "unchanged" };
struct obj obj2 = { "unchanged" };

int main()
{
    // pass pointers by value: the pointers
    // will be copied into the argument list
    // of the called function and the copied
    // pointers will point to the same values
    // as the original pointers
    changeStuff(&num, &obj1, &obj2);
    printf("%d\n", num);
    puts(obj1.item);
    puts(obj2.item);
    return 0;
}

Piénselo así: siempre se pasa por valor. Sin embargo, el valor de un objeto no es el objeto en sí, sino una referencia a ese objeto.

Aquí hay un ejemplo, pasando un número (un tipo primitivo)

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
}
var x = 10;
changePrimitive(x);
// x === 10

Repitiendo esto con un objeto produce diferentes resultados:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
}
var x = { val: 10 };
changeObject(x);
// x === { val: 100 }

Un ejemplo más:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
}
var x = { val: 10 };
changeObject(x);
// x === { val: 10}

En un lenguaje de bajo nivel, si desea pasar una variable por referencia, debe usar una sintaxis específica en la creación de la función:

int myAge = 14;
increaseAgeByRef(myAge);
function increaseAgeByRef(int &age) {
  *age = *age + 1;
}

El &agees una referencia a myAge, pero si desea que el valor que tiene para convertir la referencia, utilizando *age.

Javascript es un lenguaje de alto nivel que hace esta conversión por ti. Entonces, aunque los objetos se pasan por referencia, el lenguaje convierte el parámetro de referencia al valor. No es necesario utilizar &, en la definición de la función, para pasarla por referencia, tampoco *, en el cuerpo de la función, para convertir la referencia al valor, JS lo hace por usted.

Es por eso que cuando intenta cambiar un objeto dentro de una función, al reemplazar su valor (es decir age = {value:5}), el cambio no persiste, pero si cambia sus propiedades (es decir age.value = 5), sí lo hace.

Aprende más


Los valores simples dentro de las funciones no cambiarán esos valores fuera de la función (se pasan por valor), mientras que los valores complejos (se pasan por referencia).

function willNotChange(x) {

x = 1;

}

var x = 1000;

willNotChange(x);

document.write('After function call, x = ' + x + '<br>'); //still 1000

function willChange(y) {

y.num = 2;

}

var y = {num: 2000}; 

willChange(y);
document.write('After function call y.num = ' + y.num + '<br>'); //now 2, not 2000

Yo diría que es paso por copia -

Considere que los argumentos y los objetos variables son objetos creados durante el contexto de ejecución creado al comienzo de la invocación de la función, y su valor / referencia real pasado a la función simplemente se almacena en estos argumentos + objetos variables.

En pocas palabras, para los tipos primitivos, los valores se copian al comienzo de la llamada a la función, para el tipo de objeto, la referencia se copia.


¡¡Semántica!! Establecer definiciones concretas necesariamente hará que algunas respuestas y comentarios sean incompatibles, ya que no describen lo mismo incluso cuando se usan las mismas palabras y frases, pero es fundamental superar la confusión (especialmente para los nuevos programadores).

En primer lugar, hay múltiples niveles de abstracción que no todos parecen captar. Los programadores más nuevos que han aprendido en los lenguajes de 4ta o 5ta generación pueden tener dificultades para comprender conceptos familiares para ensambladores o programadores en C que no van en fases por punteros a punteros a indicadores. Paso por referencia no significa simplemente la capacidad de cambiar un objeto referenciado usando una variable de parámetro de función.

Variable : concepto combinado de un símbolo que hace referencia a un valor en una ubicación particular en la memoria. Este término es generalmente demasiado cargado para ser usado solo al discutir los detalles.

Símbolo : cadena de texto utilizada para referirse a la variable (es decir, el nombre de la variable).

Valor : Bits particulares almacenados en la memoria y referenciados usando el símbolo de la variable.

Ubicación de memoria : donde se almacena el valor de una variable. (La ubicación en sí está representada por un número independiente del valor almacenado en la ubicación).

Parámetro de función : Variable declarada en una definición de función, utilizada para hacer referencia a las variables pasadas a la función.

Argumento de la función : Variable fuera de la función que la persona que llama pasa a la función.

Variable de objeto : Variable cuyo valor subyacente básico no es el "objeto" en sí, sino que su valor es un puntero (valor de ubicación de memoria) a otra ubicación en la memoria donde se almacenan los datos reales del objeto. En la mayoría de los lenguajes de la generación superior, el aspecto "puntero" se oculta de manera efectiva mediante la falta de referencia automática en diversos contextos.

Variable primitiva : variable cuyo valor es el valor real. Incluso este concepto puede complicarse con el autoajuste y los contextos tipo objeto de varios idiomas, pero las ideas generales son que el valor de la variable es el valor real representado por el símbolo de la variable en lugar de un puntero a otra ubicación de memoria.

Los argumentos de función y los parámetros no son lo mismo. Además, el valor de una variable no es el objeto de la variable (como ya lo señalaron varias personas, pero aparentemente se ignoró). Estas distinciones son críticas para una correcta comprensión.

Pasar por valor o Llamar por compartir (para objetos): El valor del argumento de la función está COPIADO a otra ubicación de memoria a la que se hace referencia mediante el símbolo de parámetro de la función (independientemente de si está en la pila o en el montón). En otras palabras, el parámetro de función recibió una copia del valor del argumento pasado ... Y (crítico) el valor del argumento NUNCA ESTÁ ACTUALIZADO / ALTERADO / CAMBIADO por la función de llamada. Recuerde, el valor de una variable de objeto NO es el objeto en sí, sino que es el puntero al objeto, por lo que al pasar una variable de objeto por valor se copia el puntero a la variable de parámetro de función. El valor del parámetro de la función apunta exactamente al mismo objeto en la memoria. Los datos del objeto en sí pueden modificarse directamente a través del parámetro de función, PERO el valor del argumento de la función NUNCA SE ACTUALIZA, por lo que continuará apuntando al mismoObjeto completo e incluso después de la llamada a la función (incluso si se modificaron los datos de su objeto o si el parámetro de la función tiene asignado un objeto completamente diferente). Es incorrecto concluir que el argumento de la función se pasó por referencia solo porque el objeto al que se hace referencia es actualizable a través de la variable de parámetro de la función.

Llamada / paso por referencia : el valor del argumento de la función se puede / se actualizará directamente con el parámetro de la función correspondiente. Si ayuda, el parámetro de función se convierte en un "alias" efectivo para el argumento: efectivamente se refieren al mismo valor en la misma ubicación de memoria. Si un argumento de función es una variable de objeto, la capacidad de cambiar los datos del objeto no es diferente del caso de paso por valor, ya que el parámetro de función seguirá apuntando al mismo objeto que el argumento. Pero en el caso de la variable de objeto, si el parámetro de la función se establece en un objeto completamente diferente, entonces el argumento también apuntará al objeto diferente, esto no sucede en el caso de pasar por valor.

JavaScript no pasa por referencia. Si lees atentamente, te darás cuenta de que todas las opiniones contrarias entienden mal lo que se entiende por paso por valor y concluyen falsamente que la capacidad de actualizar los datos de un objeto mediante el parámetro de función es sinónimo de "paso por valor".

Copia / copia del objeto: se crea un nuevo objeto y se copian los datos del objeto original. Esto puede ser una copia profunda o una copia superficial, pero el punto es que se crea un nuevo objeto. La creación de una copia de un objeto es un concepto separado del paso por valor. Algunos idiomas distinguen entre objetos de clase y estructuras (o similares), y pueden tener diferentes comportamientos para pasar variables de los diferentes tipos. Pero JavaScript no hace nada como esto automáticamente cuando pasa variables de objeto. Pero la ausencia de clonación automática de objetos no se traduce en una referencia paso a paso.


Esta es una explicación un poco más para Pasar por valor y Pasar por referencia (Javascript). En este concepto, están hablando de pasar la variable por referencia y pasar la variable por referencia.

Pase por valor (tipo primitivo)

var a = 3;
var b = a;

console.log(a); // a = 3
console.log(b); // b = 3

a=4;
console.log(a); // a = 4
console.log(b); // b = 3
  • se aplica a todos los tipos primitivos en JS (cadena, número, booleano, indefinido, nulo).
  • a se asigna una memoria (por ejemplo, 0x001) yb crea una copia del valor en la memoria (por ejemplo, 0x002).
  • Por lo tanto, cambiar el valor de una variable no afecta a la otra, ya que ambos residen en dos ubicaciones diferentes.

Pasar por referencia (objetos)

var c = { "name" : "john" };    
var d = c;

console.log(c); // { "name" : "john" }
console.log(d); // { "name" : "john" }

c.name = "doe"; 

console.log(c); // { "name" : "doe" }    
console.log(d); // { "name" : "doe" }
  • El motor JS asigna el objeto a la variable c, apunta a algo de memoria, por ejemplo (0x012)
  • cuando d = c, en este paso d apunta a la misma ubicación (0x012).
  • cambiando el valor de cualquier valor de cambios tanto para la variable.
  • las funciones son objetos

Caso especial, Pasar por referencia (objetos)

c = {"name" : "jane"}; 
console.log(c); // { "name" : "jane" }    
console.log(d); // { "name" : "doe" }
  • El operador igual (=) configura un nuevo espacio de memoria o dirección

Hay un poco de debate sobre el uso del término "paso por referencia" en JS here , pero para responder a su pregunta:

Un objeto se pasa automáticamente por referencia, sin la necesidad de indicarlo específicamente

(Del artículo mencionado anteriormente.)


He leído estas respuestas varias veces, pero REALMENTE no lo entendí hasta que me enteré de la definición técnica de "Llamar compartiendo", como la llama Barbara Liskov.

La semántica de la llamada al compartir difiere de la llamada por referencia en que las asignaciones a los argumentos de la función dentro de la función no son visibles para la persona que llama (a diferencia de la semántica de referencia) [cita requerida], por lo que, por ejemplo, si se pasó una variable, no es posible para simular una asignación en esa variable en el alcance de la persona que llama. Sin embargo, como la función tiene acceso al mismo objeto que la persona que llama (no se realiza ninguna copia), las mutaciones en esos objetos, si los objetos son mutables, dentro de la función son visibles para la persona que llama, lo que puede parecer que difiere de la llamada por el valor semántica. Las mutaciones de un objeto mutable dentro de la función son visibles para la persona que llama porque el objeto no se copia ni se clona, ​​sino que se comparte.

Es decir, las referencias de los parámetros se pueden modificar si vas y accedes al valor del parámetro en sí. Por otro lado, la asignación a un parámetro desaparecerá después de la evaluación, y la persona que llama a la función no podrá acceder a ella.


La explicación más breve que encontré fue en la guía de estilo AirBNB :

  • Primitivas : cuando accede a un tipo primitivo, trabaja directamente en su valor

    • cuerda
    • número
    • booleano
    • nulo
    • indefinido

P.ej:

var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
  • Complejo : cuando accede a un tipo complejo, trabaja en una referencia a su valor

    • objeto
    • formación
    • función

P.ej:

var foo = [1, 2],
    bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9

En efecto, los tipos primitivos se pasan por valor y los tipos complejos se pasan por referencia.


Para los abogados de lenguaje de programación, he revisado las siguientes secciones de ECMAScript 5.1 (que es más fácil de leer que la edición más reciente) y llego a asking en la lista de correo de ECMAScript.

TL; DR : Todo se pasa por valor, pero las propiedades de los Objetos son referencias, y la definición de Objeto carece asombrosamente del estándar.

Construcción de listas de argumentos

La sección 11.2.4 "Listas de argumentos" dice lo siguiente al generar una lista de argumentos que consta de solo 1 argumento:

La ArgumentList de producción: AssignmentExpression se evalúa de la siguiente manera:

  1. Sea ref el resultado de evaluar AssignmentExpression.
  2. Que arg sea GetValue (ref).
  3. Devuelve una lista cuyo único artículo es arg.

La sección también enumera los casos donde la lista de argumentos tiene 0 o> 1 argumentos.

Así, todo se pasa por referencia.

Acceso a las propiedades del objeto.

Sección 11.2.1 "Accesores de propiedades"

La producción MemberExpression: MemberExpression [Expresión] se evalúa de la siguiente manera:

  1. Deje que baseReference sea el resultado de evaluar MemberExpression.
  2. Deje que baseValue sea GetValue (baseReference).
  3. Deje que propertyNameReference sea el resultado de evaluar Expresión.
  4. Deje que propertyNameValue sea GetValue (propertyNameReference).
  5. Llame a CheckObjectCoercible (baseValue).
  6. Deje que propertyNameString sea ToString (propertyNameValue).
  7. Si la producción sintáctica que se está evaluando está contenida en un código de modo estricto, permita que estrictamente sea verdadero, de lo contrario, sea estrictamente falso.
  8. Devuelve un valor de tipo Reference cuyo valor base es baseValue y cuyo nombre de referencia es propertyNameString, y cuyo indicador de modo estricto es estricto.

Por lo tanto, las propiedades de los objetos están siempre disponibles como referencia.

En referencia

Se describe en la sección 8.7 "El tipo de especificación de referencia", que las referencias no son tipos reales en el idioma, solo se usan para describir el comportamiento de los operadores de eliminación, tipo y asignación.

Definición de "Objeto"

Se define en la edición 5.1 que "Un objeto es una colección de propiedades". Por lo tanto, podemos inferir, que el valor del objeto es la colección, pero en cuanto a cuál es el valor de la colección está mal definido en la especificación y requiere un poco de effort para comprenderlo.


Una forma fácil de determinar si algo es "pasar por referencia" es si puede escribir una función de "intercambio". Por ejemplo, en C, puedes hacer:

void swap(int *i, int *j)
{
    int t;
    t = *i;
    *i = *j;
    *j = t;
}

Si no puede hacer el equivalente de eso en Javascript, no es "pasar por referencia".







pass-by-value