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

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. :)


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

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


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>

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.


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

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

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


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. :)


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

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.


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

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.


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

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

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

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

-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(); 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.