significado reservadas palabras funcion entendiendo ejemplo cual contexto javascript new-operator

javascript - funcion - palabras reservadas y su significado



¿Cuál es la palabra clave ''nueva'' en JavaScript? (14)

así que probablemente no sea para crear instancias de objeto

Se utiliza exactamente para eso. Se define un constructor de funciones así:

function Person(name) { this.name = name; } var john = new Person(''John'');

Sin embargo, el beneficio adicional que tiene ECMAScript es que puede extenderse con la propiedad .prototype , por lo que podemos hacer algo como ...

Person.prototype.getName = function() { return this.name; }

Todos los objetos creados a partir de este constructor tendrán ahora un getName debido a la cadena de prototipo a la que tienen acceso.

La new palabra clave en JavaScript puede ser bastante confusa cuando se la encuentra por primera vez, ya que las personas tienden a pensar que JavaScript no es un lenguaje de programación orientado a objetos.

  • ¿Qué es?
  • ¿Qué problemas resuelve?
  • ¿Cuándo es apropiado y cuándo no?

Resumen:

La new palabra clave se usa en javascript para crear un objeto a partir de una función constructora. La new palabra clave debe colocarse antes de la llamada de la función del constructor y hará lo siguiente:

  1. Crea un nuevo objeto
  2. Establece el prototipo de este objeto en la propiedad prototipo de la función constructora.
  3. Enlaza la palabra clave this al objeto recién creado y ejecuta la función constructora
  4. Devuelve el objeto recién creado

Ejemplo:

function Dog (age) { this.age = age; } const doggie = new Dog(12); console.log(doggie); console.log(doggie.__proto__ === Dog.prototype) // true

Lo que sucede exactamente:

  1. const doggie dice: Necesitamos memoria para declarar una variable.
  2. El operador de asignación = dice: vamos a inicializar esta variable con la expresión después de =
  3. La expresión es new Dog(12) . El motor JS ve la nueva palabra clave, crea un nuevo objeto y establece el prototipo en Dog.prototype
  4. La función constructora se ejecuta con this valor establecido en el nuevo objeto. En este paso es donde se asigna la edad al nuevo objeto perrito creado.
  5. El objeto recién creado se devuelve y se asigna a la variable doggie.

Para principiantes entenderlo mejor.

Prueba el siguiente código en la consola del navegador.

function Foo() { return this; } var a = Foo(); //returns window object var b = new Foo(); //returns empty object of foo a instanceof Window; // true a instanceof Foo; // false b instanceof Window; // false b instanceof Foo; // true

Ahora puedes leer la respuesta wiki de la comunidad :)


A veces el código es más fácil que las palabras:

var func1 = function (x) { this.x = x; } // used with ''new'' only var func2 = function (x) { var z={}; z.x = x; return z; } // used both ways func1.prototype.y = 11; func2.prototype.y = 12; A1 = new func1(1); // has A1.x AND A1.y A2 = func1(1); // undefined (''this'' refers to ''window'') B1 = new func2(2); // has B1.x ONLY B2 = func2(2); // has B2.x ONLY

para mí, siempre y cuando no prototipo, uso el estilo de func2 ya que me da un poco más de flexibilidad dentro y fuera de la función.


Además de la respuesta de Daniel Howard, esto es lo que hace new (o al menos parece hacer):

function New(func) { var res = {}; if (func.prototype !== null) { res.__proto__ = func.prototype; } var ret = func.apply(res, Array.prototype.slice.call(arguments, 1)); if ((typeof ret === "object" || typeof ret === "function") && ret !== null) { return ret; } return res; }

Mientras

var obj = New(A, 1, 2);

es equivalente a

var obj = new A(1, 2);


Bueno, JavaScript por sí mismo puede diferir enormemente de una plataforma a otra, ya que siempre es una implementación de la especificación original EcmaScript.

En cualquier caso, independientemente de la implementación, todas las implementaciones de JavaScript que cumplan con la especificación EcmaScript correcta, le proporcionarán un lenguaje orientado a objetos. Según la norma ES:

ECMAScript es un lenguaje de programación orientado a objetos para realizar cálculos y manipular objetos computacionales dentro de un entorno host.

Ahora que estamos de acuerdo en que JavaScript es una implementación de EcmaScript y, por lo tanto, es un lenguaje orientado a objetos. La definición de la new operación en cualquier lenguaje orientado a objetos dice que dicha palabra clave se usa para crear una instancia de objeto de una clase de un tipo determinado (incluidos los tipos anónimos, en casos como C #).

En EcmaScript no utilizamos clases, como puede leer de las especificaciones:

ECMAScript no usa clases como las de C ++, Smalltalk o Java. En su lugar, los objetos se pueden crear de varias maneras, incluso a través de una notación literal o a través de constructores que crean objetos y luego ejecutan el código que inicializa todos o parte de ellos asignando valores iniciales a sus propiedades. Cada constructor es una función que tiene una propiedad denominada - prototype ‖ que se utiliza para implementar la herencia basada en prototipos y las propiedades compartidas. Los objetos son creados por
utilizando constructores en nuevas expresiones; por ejemplo, new Date (2009,11) crea un nuevo objeto Date. Invocar un constructor sin usar un nuevo tiene consecuencias que dependen del constructor. Por ejemplo, Date () produce una representación de cadena de la fecha y hora actual en lugar de un objeto.


Hace 5 cosas:

  1. Crea un nuevo objeto. El tipo de este objeto es simplemente objeto .
  2. Establece la propiedad interna, inaccesible, de este nuevo objeto [prototipo]] (es decir, __proto__ ) como el objeto prototipo externo, accesible de la función constructora (cada objeto de función tiene automáticamente una propiedad prototipo ).
  3. Hace que this variable apunte al objeto recién creado.
  4. Ejecuta la función constructora, utilizando el objeto recién creado cada vez que se menciona.
  5. Devuelve el objeto recién creado, a menos que la función constructora devuelva una referencia de objeto no null . En este caso, se devuelve esa referencia de objeto.

Nota: la función constructora refiere la función después de la new palabra clave, como en

new ConstructorFunction(arg1, arg2)

Una vez hecho esto, si se solicita una propiedad no definida del nuevo objeto, la secuencia de comandos verificará el objeto [[prototype]] del objeto en su lugar. Así es como puede obtener algo similar a la herencia de clase tradicional en JavaScript.

La parte más difícil de esto es el punto número 2. Cada objeto (incluidas las funciones) tiene esta propiedad interna llamada [[prototipo]] . Solo se puede establecer en el momento de la creación del objeto, ya sea con nuevo , con Object.create , o basado en el literal (funciones predeterminadas para Function.prototype, números para Number.prototype, etc.). Solo se puede leer con Object.getPrototypeOf (someObject) . No hay otra manera de establecer o leer este valor.

Las funciones, además de la propiedad oculta [[prototype]] , también tienen una propiedad llamada prototype , y es a esto a la que puede acceder y modificar para proporcionar propiedades y métodos heredados para los objetos que crea.

Aquí hay un ejemplo:

ObjMaker = function() {this.a = ''first'';}; // ObjMaker is just a function, there''s nothing special about it that makes // it a constructor. ObjMaker.prototype.b = ''second''; // like all functions, ObjMaker has an accessible prototype property that // we can alter. I just added a property called ''b'' to it. Like // all objects, ObjMaker also has an inaccessible [[prototype]] property // that we can''t do anything with obj1 = new ObjMaker(); // 3 things just happened. // A new, empty object was created called obj1. At first obj1 was the same // as {}. The [[prototype]] property of obj1 was then set to the current // object value of the ObjMaker.prototype (if ObjMaker.prototype is later // assigned a new object value, obj1''s [[prototype]] will not change, but you // can alter the properties of ObjMaker.prototype to add to both the // prototype and [[prototype]]). The ObjMaker function was executed, with // obj1 in place of this... so obj1.a was set to ''first''. obj1.a; // returns ''first'' obj1.b; // obj1 doesn''t have a property called ''b'', so JavaScript checks // its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype // ObjMaker.prototype has a property called ''b'' with value ''second'' // returns ''second''

Es como una herencia de clase porque ahora, todos los objetos que realice utilizando el new ObjMaker() también parecerá haber heredado la propiedad ''b''.

Si quieres algo como una subclase, entonces haz esto:

SubObjMaker = function () {}; SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated! // Because we used ''new'', the [[prototype]] property of SubObjMaker.prototype // is now set to the object value of ObjMaker.prototype. // The modern way to do this is with Object.create(), which was added in ECMAScript 5: // SubObjMaker.prototype = Object.create(ObjMaker.prototype); SubObjMaker.prototype.c = ''third''; obj2 = new SubObjMaker(); // [[prototype]] property of obj2 is now set to SubObjMaker.prototype // Remember that the [[prototype]] property of SubObjMaker.prototype // is ObjMaker.prototype. So now obj2 has a prototype chain! // obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype obj2.c; // returns ''third'', from SubObjMaker.prototype obj2.b; // returns ''second'', from ObjMaker.prototype obj2.a; // returns ''first'', from SubObjMaker.prototype, because SubObjMaker.prototype // was created with the ObjMaker function, which assigned a for us

Leí un montón de basura sobre este tema antes de encontrar finalmente esta página , donde esto se explica muy bien con diagramas bonitos.


JavaScript es un lenguaje de programación orientado a objetos y se usa exactamente para crear instancias. Se basa en prototipos, en lugar de en clases, pero eso no significa que no esté orientado a objetos.


Javascript es un lenguaje de programación dinámico que soporta el paradigma de programación orientado a objetos, y se usa para crear nuevas instancias de objetos.

Las clases no son necesarias para los objetos. Javascript es un lenguaje basado en prototipos .


La new palabra clave cambia el contexto en el que se ejecuta la función y devuelve un puntero a ese contexto.

Cuando no usa la new palabra clave, el contexto bajo el cual se ejecuta la función Vehicle() es el mismo contexto desde el que está llamando la función Vehicle . La palabra clave this se referirá al mismo contexto. Cuando utiliza un new Vehicle() , se crea un nuevo contexto, por lo que la palabra clave dentro de la función se refiere al nuevo contexto. Lo que obtienes a cambio es el contexto recién creado.


La new palabra clave crea instancias de objetos utilizando funciones como constructor. Por ejemplo:

var Foo = function() {}; Foo.prototype.bar = ''bar''; var foo = new Foo(); foo instanceof Foo; // true

Las instancias heredan del prototype de la función constructora. Así que dado el ejemplo anterior ...

foo.bar; // ''bar''


La new palabra clave es para crear nuevas instancias de objetos. Y sí, javascript es un lenguaje de programación dinámico, que soporta el paradigma de programación orientado a objetos. La convención sobre la denominación de los objetos es, siempre use letras mayúsculas para los objetos que se supone deben ser instanciados por la nueva palabra clave.

obj = new Element();


Supongamos que tiene esta función:

var Foo = function(){ this.A = 1; this.B = 2; };

Si llamas a esto como una función independiente así:

Foo();

La ejecución de esta función agregará dos propiedades al objeto de la window ( A y B ). Lo agrega a la window porque la window es el objeto que llamó a la función cuando la ejecutó de esa manera, y this en una función es el objeto que llamó a la función. En Javascript al menos.

Ahora, llámalo así con new :

var bar = new Foo();

Lo que sucede cuando agrega new a una llamada de función es que se crea un nuevo objeto (solo var bar = new Object() ) y que this dentro de la función apunta al nuevo Object que acaba de crear, en lugar de al objeto que llamó la función. Así que bar ahora es un objeto con las propiedades A y B Cualquier función puede ser un constructor, simplemente no siempre tiene sentido.


Ya hay algunas respuestas muy buenas, pero estoy publicando una nueva para enfatizar mi observación sobre el caso III a continuación sobre lo que sucede cuando tiene una declaración de devolución explícita en una función que está iniciando. Echa un vistazo a los siguientes casos:

Caso I :

var Foo = function(){ this.A = 1; this.B = 2; }; console.log(Foo()); //prints undefined console.log(window.A); //prints 1

Arriba hay un caso simple de llamar a la función anónima señalada por Foo . Cuando llamas a esta función devuelve undefined . Como no hay una declaración de devolución explícita, el intérprete de JavaScript inserta a la fuerza una return undefined; Declaración al final de la función. Aquí la ventana es el objeto de invocación (contextual this ) que obtiene nuevas propiedades A y B

Caso II :

var Foo = function(){ this.A = 1; this.B = 2; }; var bar = new Foo(); console.log(bar()); //illegal isn''t pointing to a function but an object console.log(bar.A); //prints 1

Aquí el intérprete de JavaScript al ver la new palabra clave crea un nuevo objeto que actúa como el objeto de invocación (contextualizado) de la función anónima señalada por Foo . En este caso, A y B convierten en propiedades en el objeto recién creado (en lugar de objeto de ventana). Como no tiene ninguna declaración de devolución explícita, el intérprete de JavaScript inserta a la fuerza una declaración de devolución para devolver el nuevo objeto creado debido al uso de una new palabra clave.

Caso III :

var Foo = function(){ this.A = 1; this.B = 2; return {C:20,D:30}; }; var bar = new Foo(); console.log(bar.C);//prints 20 console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

Aquí, nuevamente, el intérprete de JavaScript al ver la new palabra clave crea un nuevo objeto que actúa como el objeto de invocación (contextualizado) de la función anónima señalada por Foo . Nuevamente, A y B convierten en propiedades en el objeto recién creado. Pero esta vez tiene una declaración de devolución explícita, por lo que el intérprete de JavaScript no hará nada por sí mismo.

Lo que hay que tener en cuenta en el caso III es que el objeto que se está creando debido a una new palabra clave se perdió de su radar. bar realidad apunta a un objeto completamente diferente que no es el creado por el intérprete de JavaScript debido a una new palabra clave.