Constructores en objetos JavaScript

Respuestas:

408

Usando prototipos:

function Box(color) // Constructor
{
    this.color = color;
}

Box.prototype.getColor = function()
{
    return this.color;
};

Ocultar "color" (algo parecido a una variable de miembro privado):

function Box(col)
{
   var color = col;

   this.getColor = function()
   {
       return color;
   };
}

Uso:

var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
Mella
fuente
3
@BorisB, sí, esto define el color y getColor en el objeto Box, de lo contrario, está asignando variables en el ámbito habitual.
Nick
44
@Jeach sí lo hace. He proporcionado un fragmento alternativo que se esconde color. Te sugiero que uses en gran medida por preferencia personal (protección versus simplicidad)
Nick
66
@CamiloMartin Aunque no siempre es necesario, hacer que una variable sea "privada" (o en este caso, innombrable) puede ser una forma útil de evitar que el código externo se vuelva dependiente de los detalles de implementación de su clase. Incluso la indicación de qué elementos de la clase son públicos / privados puede ser útil para usuarios externos.
Nick
49
varhace una variable privada. thishace una variable pública
EhevuTov
3
@AlanKis (al menos en algunos motores Javascript) el seguimiento de la pila en el caso de la función anónima ni siquiera lo menciona Foo, mientras que en el último caso sabrá que se Fooestá llamando. Muy útil para la depuración.
Joachim Isaksson
248

Aquí hay una plantilla que a veces uso para comportamientos similares a OOP en JavaScript. Como puede ver, puede simular miembros privados (tanto estáticos como de instancia) utilizando cierres. Lo new MyClass()que devolverá es un objeto con solo las propiedades asignadas al thisobjeto y en el prototypeobjeto de la "clase".

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
        // private
        var id = nextId++;
        var name = 'Unknown';

        // public (this instance only)
        this.get_id = function () { return id; };

        this.get_name = function () { return name; };
        this.set_name = function (value) {
            if (typeof value != 'string')
                throw 'Name must be a string';
            if (value.length < 2 || value.length > 20)
                throw 'Name must be 2-20 characters long.';
            name = value;
        };
    };

    // public static
    cls.get_nextId = function () {
        return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
        announce: function () {
            alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
                  'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
        }
    };

    return cls;
})();

Me preguntaron sobre la herencia usando este patrón, así que aquí va:

// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
    // We use an intermediary empty constructor to create an
    // inheritance chain, because using the super class' constructor
    // might have side effects.
    var construct = function () {};
    construct.prototype = superCls.prototype;
    cls.prototype = new construct;
    cls.prototype.constructor = cls;
    cls.super = superCls;
}

var MyChildClass = (function () {
    // constructor
    var cls = function (surName) {
        // Call super constructor on this instance (any arguments
        // to the constructor would go after "this" in call(…)).
        this.constructor.super.call(this);

        // Shadowing instance properties is a little bit less
        // intuitive, but can be done:
        var getName = this.get_name;

        // public (this instance only)
        this.get_name = function () {
            return getName.call(this) + ' ' + surName;
        };
    };
    inherit(cls, MyClass); // <-- important!

    return cls;
})();

Y un ejemplo para usarlo todo:

var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"

var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"

alert(john instanceof MyClass); // true

Como puede ver, las clases interactúan correctamente entre sí (comparten la identificación estática MyClass, el announcemétodo usa el get_namemétodo correcto , etc.)

Una cosa a tener en cuenta es la necesidad de sombrear las propiedades de instancia. En realidad, puede hacer que la inheritfunción pase por todas las propiedades de instancia (usando hasOwnProperty) que son funciones, y agregar automáticamente una super_<method name>propiedad. Esto le permitiría llamar en this.super_get_name()lugar de almacenarlo en un valor temporal y llamarlo enlazado usando call.

Sin embargo, para los métodos en el prototipo no necesita preocuparse por lo anterior, si desea acceder a los métodos prototipo de la superclase, simplemente puede llamar this.constructor.super.prototype.methodName. Si desea que sea menos detallado, por supuesto, puede agregar propiedades de conveniencia. :)

Blixt
fuente
77
Solo una nota sobre la cls.prototypeparte: "compartido entre instancias" es solo para leer el valor (llamar announce). Si establece myClassInstance.announceotro valor, crea una nueva propiedad en myClassInstance, por lo que solo se aplica a ese objeto, no a otras instancias de la clase. MyClass.prototype.announceSin embargo, asignar a afectará a todas las instancias.
Matthew Crumley
1
No hay problema, me alegro de ser de ayuda! :)
Blixt
2
¡Gracias! Muy gustado! ¿Podría mostrar un ejemplo de herencia de clase en este enfoque?
Dmitrij Golubev
2
@DmitrijGolubev, Brad Dwyer y Nathan C. Tresch: agregué herencia, pero se está volviendo bastante complicado, por lo que generalmente le aconsejaría que elija una solución más simple, a menos que necesite una herencia tan dura en JavaScript (que en realidad es solo un lenguaje prototípico).
Blixt
1
@guiomie Es un método "público estático", por lo que lo llamaría en la función de constructor (la "clase"), no en la instancia:MyClass.get_nextId()
Blixt
166

Me parece que la mayoría de ustedes están dando ejemplos de getters y setters que no son constructores, es decir, http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

lunched-dan estaba más cerca pero el ejemplo no funcionó en jsFiddle.

Este ejemplo crea una función de constructor privado que solo se ejecuta durante la creación del objeto.

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   var __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

Si desea asignar propiedades públicas, entonces el constructor podría definirse como tal:

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   var __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black
Jon
fuente
45
¿Cómo es que esta no es la respuesta # 1? Solo Jon creó un constructor con parámetros.
Rap
1
¿Hay alguna manera de que podamos obtener un ejemplo de herencia usando este paradigma para constructores?
Nathan C. Tresch
1
El ejemplo del constructor @Rap Jon no tiene parámetros, ya que es Box()función :). Pero este ejemplo, así como los ejemplos en las otras respuestas, pueden extenderse fácilmente para aceptar parámetros.
Alexander Stepaniuk
2
@AndersonGreen puede agregar un parámetro a Box y luego pasarlo al constructor privado como parámetro de función.
Gautham C.
1
No hay necesidad de "constructores privados". Simplemente haga su construcción en la Boxfunción y estará listo (todavía es "privado"). "Privado" en Javascript solo significa accesible a través del alcance léxico; No es necesario asignar a los miembros. Además: este código está mal. Crea una __constructvariable global , que es bastante mala. vardebe usarse para restringir el alcance de __construct.
mattbasta
23

Entonces, ¿cuál es el punto de la propiedad "constructor"? ¿No puede averiguar dónde podría ser útil, alguna idea?

El objetivo de la propiedad del constructor es proporcionar alguna forma de pretender que JavaScript tiene clases. Una de las cosas que no puede hacer es cambiar el constructor de un objeto después de haberlo creado. Es complicado.

Escribí un artículo bastante completo sobre él hace unos años: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

Joost Diepenmaat
fuente
El punto es usar la palabra clave "nueva". "d = new Drofto ()" crea un objeto vacío y ejecuta la función Drofto con dicho nuevo objeto delimitado como "this". La función Drofto es libre de devolver cualquier cosa, pero es habitual devolver algo para ser considerado como miembro de la clase Drofto.
Juan Lanus
16

Ejemplo aquí: http://jsfiddle.net/FZ5nC/

Prueba esta plantilla:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
  v1: null
 ,v2: null
 ,f1: function Name_Space_ClassName_f1(){}
}

//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;

//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>

Debe ajustar su espacio de nombres si está definiendo una clase estática:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

Clase de ejemplo:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
    this.Width = width;
    this.Height = height;
    this.Color = color;
}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
  Width: null
 ,Height: null
 ,Color: null
 ,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext("2d");
    context.fillStyle = this.Color;
    context.fillRect(x, y, this.Width, this.Height);
 }
}

//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;

//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
    return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
    return new Shape.Rectangle(50,25,'#ff0000');
}
</script>

Ejemplo de instanciación:

<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");

var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);

var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);

Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>

Las funciones de aviso se definen como AB = función A_B (). Esto es para hacer que su script sea más fácil de depurar. Abra el panel Inspeccionar elemento de Chrome, ejecute este script y expanda la traza inversa de depuración:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};

//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
    A.Func.That.Does.Not.Exist();
}

Fail.Test();
</script>
bitlather
fuente
Ejemplo agregado. También se agregó información sobre cómo mejorar la salida de depuración.
bitlather
1
Probablemente porque agrega un nivel innecesario de complejidad al problema. Es difícil encontrar la respuesta en su publicación debido al espaciamiento pedante del nombre y la declaración de clase estática. No me malinterpreten, es buena información, pero ciertamente es más confuso que útil si está tratando de poner un pie en la puerta de la comprensión. Soy medio competente en JS y apenas entiendo lo que estás haciendo aquí, o por qué es relevante para "¿Cómo constructor?"
Bmo
1
Gracias por la información, Bmo. Fue una publicación larga, pero es porque no entiendo el uso de un constructor si no está vinculado a un objeto bien definido y una implementación de clase estática. Al aprender C ++ o Java, debe aprender cómo implementar clases junto con cómo implementar constructores. El desarrollo web se ha vuelto mucho más agradable desde que me topé con este método de escribir javascript, y solo quería compartirlo. Moví el violín hacia arriba para que sea más fácil de encontrar. Espero que eso aclare cualquier confusión.
bitlather
1
@Bmo ¿Es en serio que las dos líneas sobre el espacio de nombres hacen que sea difícil encontrar el constructor exactamente debajo, especialmente teniendo en cuenta el comentario Constructor: DEBE ESTAR EN LA PARTE SUPERIOR DEL ARCHIVO? Brindar un ejemplo con el espacio de nombres es muy bienvenido, la comunidad de desarrollo de javascript ignora ciegamente los espacios de nombres, causando errores difíciles de encontrar cuando los nombres chocan. Es triste ver que los desarrolladores de js piensan que si copian un texto de una publicación en Internet y hacen algo similar a lo que necesitan, su trabajo está completo.
user3285954
1
El principal problema con js y el desarrollo web en general es que la mayoría de los desarrolladores ignoran todas las prácticas que la industria creó en más de 50 años y piensan que si pueden hacer una llamada ajax son el rey. Es muy triste ver que tomó tantos años comenzar a usar patrones y prácticas bien conocidos en javascript.
user3285954
10

Este es un constructor:

function MyClass() {}

Cuando tu lo hagas

var myObj = new MyClass();

MyClass se ejecuta y se devuelve un nuevo objeto de esa clase.

Satish N Ramteare
fuente
1
Para aclarar, lo que esto significa está en la parte superior de su clase, puede decirlo alert(valuePassedInAsArgument);y esto se ejecutará una vez para cada instanciación, por lo que toda la clase es el propio constructor.
Martin Lyne
new object is returned of that class- ¿No es más como un nuevo objeto devuelto de esa función?
Don Cheadle
en funciones de JavaScript son objetos
Leo
8

Encontré este tutorial muy útil. Este enfoque es utilizado por la mayoría de los complementos de jQuery.

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

Ahora ,

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
anasanjaria
fuente
10
Me estremezco cada vez que veo gente usandoklass
Madbreaks
8

Este patrón me ha servido bien. Con este patrón, puede crear clases en archivos separados, cargarlos en su aplicación general "según sea necesario".

// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};

// "Package" 
// Similar to how you would establish a package in other languages
(function() {

// "Class"
var MyClass = function(params) {
    this.initialize(params);
}

    // "Private Static" vars 
    //    - Only accessible to functions in this class.
    //    - Doesn't get wiped out when we create a new instance.
    var countInstances = 0;
    var allInstances = [];

    // "Private Static" functions 
    //    - Same as above, but it's a function accessible 
    //      only to other functions in this class.
    function doSomething(){
    }

    // "Public Static" vars
    //    - Everyone has access.
    //    - Doesn't get wiped out when we create a new instance.
    MyClass.counter = 0;

    // "Public Static" functions
    //    - Same as above, but anyone can call this "static method".
    //    - Kinda like a singleton class situation.
    MyClass.foobar = function(){
    }

    // Public properties and methods are built into the "prototype"
    //    - This is how each instance can become unique unto itself.
    //    - Establishing "p" as "local" (Static Private) variable 
    //      simply so we don't have to keep typing "MyClass.prototype" 
    //      for each property and function.
var p = MyClass.prototype;

    // "Public" vars
    p.id = null;
    p.firstname = null;
    p.lastname = null;

    // "Private" vars
    //    - Only used by "this" instance.
    //    - There isn't "true" privacy for each 
    //      instance so we have to fake it. 
    //    - By tradition, we indicate "privacy"  
    //      by prefixing it with an underscore. 
    //    - So technically, anyone can access, but we simply 
    //      don't tell anyone about it (e.g. in your API)
    //      so no one knows about it :)
    p._foo = null;

    p.initialize = function(params){
        this.id = MyClass.counter++;
        this.firstname = params.firstname;
        this.lastname = params.lastname;
        MyClass.counter++;
        countInstances++;
        allInstances.push(this);
    }

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ".  Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
    }


// Assign class to app
myApp.MyClass = MyClass;

// Close the "Package"
}());

// Usage example:
var bob = new myApp.MyClass({   firstname   :   "bob",
                                lastname    :   "er"
                            });

bob.doAlert("hello there");
Beto
fuente
Esas son variables de instancia pero tienen accesibilidad "pública", no "privada" como en C ++ o Java.
Potatoswatter
¿Cómo harías para crear una variable privada (en el sentido clásico) que sea relativa a la instancia, pero no común a todas las instancias?
bob
Vea el sitio de Douglas Crockford , es uno de los diseñadores de idiomas y una autoridad principal. No siempre sigo sus patrones, pero en general una variable privada es un local varen el constructor (o argumento de función, o en una función similar a un constructor).
Potatoswatter
Gracias por el consejo ... la siguiente página explica lo que estaba buscando: javascript.crockford.com/private.html
bob
Oh, perdón por no probar el enlace: P
Potatoswatter
8

Sí, puede definir un constructor dentro de una declaración de clase como esta:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
Bruno
fuente
para vaersion IE> 12
zloctb
Para la versión IE> = 12 :) msdn.microsoft.com/en-au/library/dn802832(v=vs.94).aspx
Bruno
1
Esta es la única respuesta real a la pregunta. : /
MarcD
6

Supongo que publicaré lo que hago con el cierre de JavaScript ya que nadie está usando el cierre todavía.

var user = function(id) {
  // private properties & methods goes here.
  var someValue;
  function doSomething(data) {
    someValue = data;
  };

  // constructor goes here.
  if (!id) return null;

  // public properties & methods goes here.
  return {
    id: id,
    method: function(params) {
      doSomething(params);
    }
  };
};

Comentarios y sugerencias a esta solución son bienvenidos. :)

Hendra Uzia
fuente
1
Un par de comentarios: 1) declaración si (! Id) no es seguro, valores como 0 o falso harán que evalúe verdadero y devuelva nulo. Supongo que desea verificar si está indefinido o nulo, en cuyo caso === nulo y === indefinido sería mejor. 2) Esto se asemeja más al patrón del Módulo ( adecuadamenteitherodod /2010/ 2010/3/JavaScript-Module-Pattern-In- Depth ) versus un constructor, la diferencia es que un Módulo devuelve un Objeto de la función, mientras que un constructor crea un objeto cuando emparejado con la nueva palabra clave, y en ese caso estaría estableciendo valores en 'esto' en lugar de un objeto.
Rico
4

Usando la muestra de Nick anterior, puede crear un constructor para objetos sin parámetros usando una declaración de retorno como la última declaración en su definición de objeto. Devuelva su función de constructor como se muestra a continuación y ejecutará el código en __construct cada vez que cree el objeto:

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();
Dan Power
fuente
1
No está devolviendo la función constructora, solo la está llamando.
David Conrad
Si intenta usar this.getColor();en la línea de arriba, alert("Object Created.");nada será alertado. Habrá un error como "getColor no está definido". Si desea construir para poder llamar a otros métodos en el objeto, debe definirse después de todos los demás métodos. Entonces, en lugar de llamar __construct();a la última línea, simplemente defina la construcción allí y colóquela ()para forzarla a ejecutarse automáticamente.
Thinsoldier
Corrección. Agregar ()al final de la definición de construcción __ todavía resultó en el error. Tuve que llamar __construct();a su propia línea como en el código original para evitar el error.
Thinsoldier
4

Tal vez se ha vuelto un poco más simple, pero a continuación es lo que se me ocurrió ahora en 2017:

class obj {
  constructor(in_shape, in_color){
    this.shape = in_shape;
    this.color = in_color;
  }

  getInfo(){
    return this.shape + ' and ' + this.color;
  }
  setShape(in_shape){
    this.shape = in_shape;
  }
  setColor(in_color){
    this.color = in_color;
  }
}

Al usar la clase anterior, tengo lo siguiente:

var newobj = new obj('square', 'blue');

//Here, we expect to see 'square and blue'
console.log(newobj.getInfo()); 

newobj.setColor('white');
newobj.setShape('sphere');

//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());

Como puede ver, el constructor toma dos parámetros y establecemos las propiedades del objeto. También modificamos el color y la forma del objeto mediante el uso de las setterfunciones, y demostramos que su cambio se mantuvo al llamar getInfo()después de estos cambios.

Un poco tarde, pero espero que esto ayude. He probado esto con una mochaunidad de prueba, y está funcionando bien.

Chim Chimz
fuente
3

Lo hacen si usa Typecript - código abierto de MicroSoft :-)

class BankAccount {
 balance: number;
 constructor(initially: number) {
 this.balance = initially;
 }
 deposit(credit: number) {
 this.balance += credit;
 return this.balance;
 }
}

El mecanografiado le permite construcciones OO 'falsas' que se compilan en construcciones javascript. Si está comenzando un proyecto grande, puede ahorrarle mucho tiempo y alcanzar la versión 1.0 de hito.

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

El código anterior se 'compila' para:

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();
Simon_Weaver
fuente
Estoy trabajando en un proyecto grande y estoy tratando de convencer a la gente de que TypeScript nos dará una oportunidad de correr. Veremos cómo va eso.
wootscootinboogie
@wootscootinboogie En un día (terminando a las 5.30 de la mañana en este momento) llegué bastante lejos y bastante cómodo con eso. Recomiendo encarecidamente leer la especificación y, si bien puede omitir la mitad de las cosas realmente importantes, se está haciendo un favor al leerla al menos una vez. Los videos de este tipo son excelentes youtube.com/user/basaratali/videos . buena suerte)
Simon_Weaver
1

En JavaScript, el tipo de invocación define el comportamiento de la función:

  • Invocación directa func()
  • Método de invocación en un objeto obj.func()
  • Invocación del constructornew func()
  • Invocación indirecta func.call()ofunc.apply()

La función se invoca como un constructor cuando se llama utilizando el newoperador:

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

var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

Cualquier instancia u objeto prototipo en JavaScript tiene una propiedad constructor, que se refiere a la función constructora.

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

Consulte esta publicación sobre la propiedad del constructor.

Dmitri Pavlutin
fuente
0

Al usar la gran plantilla de Blixt desde arriba, descubrí que no funciona bien con la herencia de varios niveles (MyGrandChildClass extendiendo MyChildClass extendiendo MyClass): se alterna al llamar al constructor del primer padre una y otra vez. Así que aquí hay una solución simple: si necesita una herencia de varios niveles, en lugar de this.constructor.super.call(this, surName);usarla chainSuper(this).call(this, surName);con la función de cadena definida de esta manera:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}
ene
fuente
0

http://www.jsoops.net/ es bastante bueno para oop en Js. Si proporciona una función y variable privada, protegida y pública, y también la característica de herencia. Código de ejemplo:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public

    pri.className = "I am A ";

    this.init = function (var1)// constructor
    {
        pri.className += var1;
    }

    pub.getData = function ()
    {
        return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
        + ", ID=" + pro.getClassId() + ")";
    }

    pri.getClassName = function () { return pri.className; }
    pro.getClassName = function () { return pri.className; }
    pro.getClassId = function () { return 1; }
});

var newA = new ClassA("Class");

//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)

//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined
user1624059
fuente
0

solo para ofrecer algo de variedad. ds.oop es una buena manera de declarar clases con constructores en javascript. Admite todos los tipos posibles de herencia (incluido 1 tipo que incluso c # no admite), así como las interfaces, lo cual es bueno.

var Color = ds.make.class({
    type: 'Color',
    constructor: function (r,g,b) { 
        this.r = r;                     /* now r,g, and b are available to   */
        this.g = g;                     /* other methods in the Color class  */
        this.b = b;                     
    }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class
dss
fuente
0

Aquí necesitamos notar un punto en el script java, es un lenguaje sin clase, sin embargo, podemos lograrlo usando funciones en el script java. La forma más común de lograr esto es crear una función en el script java y usar una nueva palabra clave para crear un objeto y usar esta palabra clave para definir propiedades y métodos. A continuación se muestra el ejemplo.

// Function constructor

   var calculator=function(num1 ,num2){
   this.name="This is function constructor";
   this.mulFunc=function(){
      return num1*num2
   };

};

var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call

//Constructors With Prototypes

var calculator=function(){
   this.name="Constructors With Prototypes";
};

calculator.prototype.mulFunc=function(num1 ,num2){
 return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call
Sheo Dayal Singh
fuente
-2

En la mayoría de los casos, debe declarar de alguna manera la propiedad que necesita antes de poder llamar a un método que pasa esta información. Si no tiene que establecer inicialmente una propiedad, puede llamar a un método dentro del objeto de esta manera. Probablemente no sea la forma más bonita de hacerlo, pero aún funciona.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Contenedor Codificado
fuente