Construtores em objetos JavaScript

Respostas:

408

Usando protótipos:

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

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

Ocultação de "cor" (lembra um pouco uma variável de membro particular):

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
usuario
fonte
3
@BorisB, sim - você define color e getColor no objeto Box, caso contrário, você está atribuindo variáveis ​​no escopo usual.
Nick
4
@Each Sim, sim. Forneci um snippet alternativo que oculta color. Eu sugiro que você usa é em grande parte uma questão de preferência pessoal (protecção contra simplicidade)
Nick
6
@CamiloMartin Embora nem sempre seja necessário, tornar uma variável "privada" (ou, nesse caso, inominável) pode ser uma maneira útil de impedir que o código externo se torne dependente dos detalhes de implementação da sua classe. Mesmo apenas a indicação de quais elementos da classe são públicos / privados pode ser útil para usuários externos.
Nick
49
varfaz uma variável privada. thisfaz uma variável pública
EhevuTov
3
@AlanKis (pelo menos em alguns mecanismos Javascript) o rastreamento de pilha no caso da função anônima nem mesmo é mencionado Foo, enquanto no último caso ele saberá que está Foosendo chamado. Muito útil para depuração.
Joachim Isaksson
248

Aqui está um modelo que às vezes uso para comportamentos semelhantes a OOP em JavaScript. Como você pode ver, você pode simular membros privados (estáticos e de instância) usando fechamentos. O new MyClass()que retornará é um objeto com apenas as propriedades atribuídas ao thisobjeto e no prototypeobjeto da "classe".

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;
})();

Fui questionado sobre herança usando esse padrão, então aqui vai:

// 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;
})();

E um exemplo para usar tudo:

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 você pode ver, as classes interagem corretamente umas com as outras (elas compartilham o ID estático MyClass, o announcemétodo usa o get_namemétodo correto etc.)

Uma coisa a observar é a necessidade de sombrear as propriedades da instância. Na verdade, você pode fazer a inheritfunção passar por todas as propriedades da instância (usando hasOwnProperty) que são funções e adicionar automaticamente uma super_<method name>propriedade. Isso permitiria que você chamasse em this.super_get_name()vez de armazená-lo em um valor temporário e chamá-lo vinculado usando call.

Para métodos no protótipo, você não precisa se preocupar com o exposto acima. Se você quiser acessar os métodos de protótipo da superclasse, basta ligar this.constructor.super.prototype.methodName. Se você quiser torná-lo menos detalhado, é claro que pode adicionar propriedades de conveniência. :)

Blixt
fonte
7
Apenas uma observação sobre a cls.prototypeparte: "compartilhado entre instâncias" é apenas para ler o valor (chamando announce). Se você definir myClassInstance.announceoutro valor, ele criará uma nova propriedade em myClassInstance, portanto, somente se aplicará a esse objeto, não a outras instâncias da classe. Atribuir a MyClass.prototype.announceafetará todas as instâncias.
Matthew Crumley
11
Não tem problema, fico feliz em ajudar! :)
Blixt
2
Obrigado! Muito gostei! Você poderia mostrar um exemplo de herança de classe nessa abordagem.
Dmitrij Golubev
2
@DmitrijGolubev, Brad Dwyer e Nathan C. Tresch: Eu adicionei herança, mas está ficando muito complicado, então eu normalmente aconselho você a usar uma solução mais simples, a menos que você precise de uma herança tão grave em JavaScript (que é realmente apenas uma linguagem prototípica).
Blixt
11
@guiomie É um método "public static" para que você chamaria isso na função de construtor (a "classe"), e não a instância:MyClass.get_nextId()
Blixt
166

Parece-me que muitos de vocês estão dando exemplos de getters e setters, não um construtor, ou seja, http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

O lunch-dan estava mais próximo, mas o exemplo não funcionou no jsFiddle.

Este exemplo cria uma função de construtor particular que é executada apenas durante a criação do 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

Se você deseja atribuir propriedades públicas, o construtor pode ser definido 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
fonte
45
Como essa não é a resposta número 1? Apenas Jon criou um construtor com parâmetros.
Rap
11
Existe alguma maneira de obter um exemplo de herança usando esse paradigma para construtores?
22812 Nathan C. Tresch
11
O exemplo do construtor do @Rap Jon não possui parâmetros, pois é a Box()função :). Mas este exemplo, bem como exemplos nas outras respostas, podem ser facilmente estendidos para aceitar parâmetros.
Alexander Stepaniuk
2
@AndersonGreen, você pode adicionar um parâmetro ao Box e passá-lo ao construtor privado como um parâmetro de função.
Gautham C.
11
Não há necessidade de "construtores privados". Apenas faça sua construção na Boxfunção e você estará pronto (ainda é "privado"). "Privado" em Javascript significa apenas acessível via escopo lexical; não há necessidade de atribuir aos membros. Além disso: esse código está errado. Ele cria uma __constructvariável global , o que é bastante ruim. vardeve ser usado para restringir o escopo de __construct.
mattbasta
23

Então, qual é o objetivo da propriedade "construtora"? Não consegue descobrir onde poderia ser útil, alguma idéia?

O objetivo da propriedade construtor é fornecer uma maneira de fingir que o JavaScript tem classes. Uma das coisas que você não pode fazer com utilidade é alterar o construtor de um objeto depois que ele é criado. É complicado.

Eu escrevi uma peça bastante abrangente sobre isso há alguns anos: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

Joost Diepenmaat
fonte
O objetivo é usar a palavra-chave "nova". "d = new Drofto ()" cria um objeto vazio e executa a função Drofto com o novo objeto delimitado como "this". A função Drofto é livre para retornar qualquer coisa, mas é habitual retornar algo para ser considerado como um membro da classe Drofto.
Juan Lanus
16

Exemplo aqui: http://jsfiddle.net/FZ5nC/

Experimente este modelo:

<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>

Você deve ajustar seu espaço para nome se estiver definindo uma classe estática:

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

Classe de exemplo:

<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>

Instanciação de exemplo:

<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>

As funções de aviso são definidas como AB = função A_B (). Isso é para facilitar a depuração do seu script. Abra o painel Inspect Element do Chrome, execute este script e expanda o backtrace de depuração:

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

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

Fail.Test();
</script>
bitlather
fonte
Exemplo adicionado. Também foram adicionadas informações sobre como melhorar a saída de depuração.
bitlather
11
Provavelmente porque adiciona um nível desnecessário de complexidade ao problema. É difícil encontrar a resposta em sua postagem devido ao espaçamento de nome pedante e à declaração de classe estática. Não me interpretem mal, é uma boa informação, mas certamente é mais confusa do que útil se você estiver tentando entender a questão. Sou parcialmente competente em JS e mal entendo o que você está fazendo aqui, ou por que é relevante para "Como faço para construir?"
BMO
11
Obrigado pela compreensão, Bmo. Foi um post longo, mas é porque eu não entendo o uso de um construtor se ele não está vinculado a um objeto bem definido e a uma implementação de classe estática. Ao aprender C ++ ou Java, você precisa aprender como implementar classes, além de como implementar construtores. O desenvolvedor da Web tornou-se muito mais agradável desde que deparei com esse método de escrever javascript, e só queria compartilhar. Movi o violino para o topo, para ficar mais fácil. Espero que isso esclareça qualquer confusão.
bitlather
11
@Bmo Você está falando sério que as duas linhas sobre namespace dificilmente encontram o construtor exatamente abaixo, especialmente considerando o comentário Construtor - DEVE ESTAR NO TOPO DO ARQUIVO? Fornecer um exemplo de namespace é muito bem-vindo, a comunidade javascript dev ignora cegamente os namespaces, causando erros difíceis de encontrar quando os nomes se chocam. É triste ver que os js devs pensam se copiam um pedaço de texto de um post na internet e fazem algo semelhante ao que precisam, pois seu trabalho está completo.
precisa saber é o seguinte
11
O principal problema com js e desenvolvimento web em geral é que a maioria dos desenvolvedores ignora todas as práticas que a indústria criou em mais de 50 anos e pensa que, se puderem fazer uma chamada de ajax, serão o rei. Tão triste ver que demorou tantos anos para começar a usar padrões e práticas conhecidas em javascript.
user3285954
10

Este é um construtor:

function MyClass() {}

Quando você faz

var myObj = new MyClass();

MyClass é executado e um novo objeto é retornado dessa classe.

Satish N Ramteare
fonte
11
Para esclarecer, o que isso significa está no topo da sua classe, você pode dizer alert(valuePassedInAsArgument);e isso será executado uma vez a cada instanciação, portanto, toda a classe é o próprio construtor.
10138 Martin-Schneider
new object is returned of that class- não é mais como um novo objeto é retornado dessa função?
31815 Don Cheadle
em funções JavaScript são objetos
Leo
8

Achei este tutorial muito útil. Essa abordagem é usada pela maioria dos plug-ins do 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;    
};

Agora ,

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
fonte
10
Eu tremo sempre que vejo as pessoas usandoklass
Madbreaks
8

Esse padrão me serviu bem. Com esse padrão, você cria classes em arquivos separados, carrega-as no seu aplicativo geral "conforme necessário".

// 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");
prumo
fonte
Essas são variáveis ​​de instância, mas elas têm acessibilidade "pública", não "privada", como em C ++ ou Java.
Potatoswatter 07/12/12
Como você criaria uma variável privada (no sentido clássico) que é relativa à instância, mas não é comum a todas as instâncias?
bob
Veja o site de Douglas Crockford , ele é um dos designers de idiomas e uma das principais autoridades. Eu nem sempre sigo seus padrões, mas, em geral, uma variável privada é um local varno construtor (ou argumento da função ou em uma função semelhante ao construtor).
Potatoswatter
Obrigado pela dica ... a seguinte página explica o que eu estava procurando: javascript.crockford.com/private.html
bob
Ah, desculpe por não testar o link: P
Potatoswatter
8

Sim, você pode definir um construtor dentro de uma declaração de classe como esta:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
Bruno
fonte
para vaersion IE> 12
zloctb
Para a versão do IE> = 12 :) msdn.microsoft.com/en-au/library/dn802832(v=vs.94).aspx
Bruno
11
Esta é a única resposta real para a pergunta. : /
MarcD 14/05
6

Acho que vou postar o que faço com o fechamento de javascript, pois ninguém está usando o fechamento ainda.

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);
    }
  };
};

Comentários e sugestões para esta solução são bem-vindos. :)

Hendra Uzia
fonte
11
Alguns comentários: 1) declaração se (! Id) não é seguro, valores como 0 ou false farão com que seja avaliado true e retorne null. Eu estou supondo que você deseja verificar indefinido ou nulo, caso em que === nulo e === indefinido seria melhor. 2) Isso se assemelha mais ao padrão Module ( versus adequadamente um bom construtor / 2010/3/JavaScript-Module-Pattern-In- Depth ) versus um construtor, a diferença de ser um Módulo retorna um Objeto da função enquanto um construtor cria um objeto quando emparelhado com a nova palavra-chave e, nesse caso, você definiria valores 'this' em vez de um objeto.
Rich
4

Usando a amostra de Nick acima, você pode criar um construtor para objetos sem parâmetros usando uma instrução de retorno como a última instrução na sua definição de objeto. Retorne sua função de construtor conforme abaixo e ele executará o código em __construct toda vez que você criar o 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
fonte
11
Você não está retornando a função construtora, está apenas chamando.
David Conrad
Se você tentar usar this.getColor();na linha acima, alert("Object Created.");nada será alertado. Ocorrerá um erro como "getColor não está definido". Se você deseja que a construção possa chamar outros métodos no objeto, ela precisa ser definida após todos os outros métodos. Então, ao invés de chamar __construct();a última linha, apenas defina a construção lá embaixo e coloque-a ()depois para forçá-la a executar automaticamente.
thinsoldier
Correção. A adição ()ao final da definição de construção ainda resultou no erro. Eu tive que chamar __construct();em sua própria linha, como no código original, para evitar o erro.
Thinsoldier
4

Talvez tenha ficado um pouco mais simples, mas abaixo está o que eu criei agora em 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;
  }
}

Ao usar a classe acima, tenho o seguinte:

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 você pode ver, o construtor utiliza dois parâmetros e definimos as propriedades do objeto. Também alteramos a cor e a forma do objeto usando as setterfunções e provamos que sua alteração permaneceu após a chamada getInfo()após essas alterações.

Um pouco tarde, mas espero que isso ajude. Eu testei isso com um mochateste de unidade e está funcionando bem.

Chim Chimz
fonte
3

Eles fazem se você usar o Typescript - código aberto da MicroSoft :-)

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

O TypeScript permite que você construa construções OO falsas que são compiladas em construções javascript. Se você estiver iniciando um projeto grande, poderá economizar muito tempo e atingir a versão 1.0 do marco.

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

O código acima é 'compilado' 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
fonte
Estou trabalhando em um projeto grande e tentando convencer as pessoas de que o TypeScript nos dará uma corrida. Vamos ver como isso vai.
Wootscootinboogie
@wootscootinboogie Em um dia (que termina às 5h30 agora), eu me sinto bem e confortável com isso. Eu recomendo fortemente a leitura das especificações e, embora você possa pular metade das coisas reais e essenciais, você está fazendo um favor a si mesmo ao lê-las pelo menos uma vez. os vídeos desse cara são excelentes youtube.com/user/basaratali/videos . boa sorte)
Simon_Weaver
1

No JavaScript, o tipo de chamada define o comportamento da função:

  • Chamada direta func()
  • Chamada de método em um objeto obj.func()
  • Chamada de construtornew func()
  • Chamada indireta func.call()oufunc.apply()

A função é chamada como um construtor ao chamar usando o 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

Qualquer objeto de instância ou protótipo em JavaScript tem uma propriedade constructor, que se refere à função do construtor.

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

Verifique esta postagem sobre a propriedade do construtor.

Dmitri Pavlutin
fonte
0

Ao usar o ótimo modelo de Blixt acima, descobri que ele não funciona bem com herança de vários níveis (MyGrandChildClass estendendo MyChildClass estendendo MyClass) - ele liga para chamar o construtor do primeiro pai repetidamente. Então, aqui está uma solução simples - se você precisar de herança em vários níveis, em vez de usar o this.constructor.super.call(this, surName);uso chainSuper(this).call(this, surName);com a função de cadeia definida assim:

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;
}
jan
fonte
0

http://www.jsoops.net/ é muito bom para oop em Js. Se fornecer variável e função pública, protegida e pública, e também recurso de Herança. Código de exemplo:

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
fonte
0

apenas para oferecer alguma variedade. O ds.oop é uma ótima maneira de declarar classes com construtores em javascript. Ele suporta todos os tipos possíveis de herança (incluindo um tipo que até o c # não suporta), bem como interfaces, o que é bom.

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
fonte
0

Aqui, precisamos observar um ponto no script java, é uma linguagem sem classe, no entanto, podemos alcançá-lo usando funções no script java. A maneira mais comum de conseguir isso é criar uma função no script java e usar a nova palavra - chave para criar um objeto e usar essa palavra - chave para definir propriedades e métodos. Abaixo está o exemplo.

// 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
fonte
-2

Na maioria dos casos, é necessário declarar de alguma forma a propriedade necessária antes de chamar um método que transmita essas informações. Se você não precisar definir inicialmente uma propriedade, basta chamar um método dentro do objeto dessa forma. Provavelmente não é a maneira mais bonita de fazer isso, mas isso ainda funciona.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Container codificado
fonte