una tipos prototipos programacion orientada objetos herencia es7 es6 ejemplos declarar clases clase javascript oop constructor instance

tipos - JavaScript: ¿Cómo crear una nueva instancia de una clase sin usar la nueva palabra clave?



prototipos en javascript (6)

¿No funciona esto?

function factory(class_) { return new class_(); }

No entiendo por qué no puedes usar lo new .

Creo que el siguiente código aclarará la pregunta.

// My class var Class = function() { console.log("Constructor"); }; Class.prototype = { method: function() { console.log("Method");} } // Creating an instance with new var object1 = new Class(); object1.method(); console.log("New returned", object1); // How to write a factory which can''t use the new keyword? function factory(clazz) { // Assume this function can''t see "Class", but only sees its parameter "clazz". return clazz.call(); // Calls the constructor, but no new object is created return clazz.new(); // Doesn''t work because there is new() method }; var object2 = factory(Class); object2.method(); console.log("Factory returned", object2);


De otra manera:

var factory = function(clazz /*, arguments*/) { var args = [].slice.call(arguments, 1); return new function() { clazz.apply(this, args) } }


Debido a que JavaScript no tiene clases, permítame volver a formular su pregunta: ¿Cómo crear un nuevo objeto basado en un objeto existente sin usar la nueva palabra clave?

Aquí hay un método que no usa "nuevo". No es estrictamente una "nueva instancia de", pero es la única forma de pensar que no usa "nuevo" (y no usa ninguna característica de ECMAScript 5).

//a very basic version that doesn''t use ''new'' function factory(clazz) { var o = {}; for (var prop in clazz) { o[prop] = clazz[prop]; } return o; }; //test var clazz = { prop1: "hello clazz" }; var testObj1 = factory(clazz); console.log(testObj1.prop1); //"hello clazz"

Podría ser elegante y configurar el prototipo, pero luego se mete en problemas con varios navegadores y estoy tratando de mantener esto simple. También es posible que desee utilizar "hasOwnProperty" para filtrar las propiedades que agrega al nuevo objeto.

Hay otras formas que usan "nuevo" pero que lo ocultan. Aquí hay uno que toma prestado de la función Object.create en JavaScript: The Good Parts de Douglas Crockford :

//Another version the does use ''new'' but in a limited sense function factory(clazz) { var F = function() {}; F.prototype = clazz; return new F(); }; //Test var orig = { prop1: "hello orig" }; var testObj2 = factory(orig); console.log(testObj2.prop1); //"hello orig"

EcmaScript 5 tiene el método Object.create que lo hará mucho mejor, pero solo es compatible con los navegadores más nuevos (por ejemplo, IE9, FF4), pero puede usar un polyfill (algo que llena las grietas), como ES5 Shim , para obtener una implementación para los navegadores más antiguos. (Consulte el artículo de John Resig sobre las nuevas características de ES5, incluido Object.create ).

En ES5 puedes hacerlo así:

//using Object.create - doesn''t use "new" var baseObj = { prop1: "hello base" }; var testObj3 = Object.create(baseObj); console.log(testObj3.prop1);

Espero que eso ayude


Si realmente no quiere usar la new palabra clave y no le importa que solo sea compatible con Firefox, puede configurar el prototipo usted mismo. Sin embargo, esto no tiene ningún sentido, ya que puedes usar la respuesta de Dave Hinton.

// This is essentially what the new keyword does function factory(clazz) { var obj = {}; obj.__proto__ = clazz.prototype; var result = clazz.call(obj); return (typeof result !== ''undefined'') ? result : obj; };


Supongo que la solución independiente del navegador sería mejor

function empty() {} function factory(clazz /*, some more arguments for constructor */) { empty.prototype = clazz.prototype; var obj = new empty(); clazz.apply(obj, Array.prototype.slice.call(arguments, 1)); return obj; }


Una forma más simple, limpia y sin "fábricas".

function Person(name) { if (!(this instanceof Person)) return new Person(name); this.name = name; } var p1 = new Person(''Fred''); var p2 = Person(''Barney''); p1 instanceof Person //=> true p2 instanceof Person //=> true