Конструкторы в объектах JavaScript - PullRequest
398 голосов
/ 11 июля 2009

Могут ли классы / объекты JavaScript иметь конструкторы? Как они созданы?

Ответы [ 19 ]

4 голосов
/ 09 августа 2017

Возможно, это стало немного проще, но вот то, что я придумал сейчас в 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;
  }
}

При использовании вышеуказанного класса у меня есть следующее:

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

Как видите, конструктор принимает два параметра, и мы устанавливаем свойства объекта. Мы также изменим цвет и форму объекта с помощью функций setter и докажем, что его изменение осталось после вызова getInfo() после этих изменений.

Немного поздно, но я надеюсь, это поможет. Я протестировал это с помощью mocha модульного тестирования, и оно работает хорошо.

4 голосов
/ 18 марта 2012

Используя приведенный выше пример Ника, вы можете создать конструктор для объектов без параметров, используя оператор возврата в качестве последнего оператора в определении вашего объекта. Верните функцию конструктора, как показано ниже, и она будет запускать код в __construct каждый раз, когда вы создаете объект:

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

  this.color = '';

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

   __construct();
}

var b = new Box();
3 голосов
/ 23 мая 2014

Они делают, если вы используете Typescript - с открытым исходным кодом от MicroSoft: -)

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

Typescript позволяет вам «подделывать» OO-конструкции, которые скомпилированы в javascript-конструкции. Если вы начинаете большой проект, он может сэкономить вам много времени, и он только что достиг версии milestone 1.0.

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

Приведенный выше код компилируется в:

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();
1 голос
/ 02 мая 2016

В JavaScript тип вызова определяет поведение функции:

  • Прямой вызов func()
  • Вызов метода для объекта obj.func()
  • Конструктор вызов new func()
  • Косвенный вызов func.call() или func.apply()

Функция вызывается как конструктор при вызове с использованием оператора new:

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

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

Любой объект экземпляра или прототипа в JavaScript имеет свойство constructor, которое ссылается на функцию конструктора.

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

Проверьте этот пост о свойстве конструктора.

0 голосов
/ 27 сентября 2017

Здесь мы должны обратить внимание на один момент в java-скрипте, это язык без классов, однако мы можем достичь этого, используя функции в java-скрипте. Наиболее распространенный способ достижения этого - создать функцию в java-скрипте и использовать new ключевое слово для создания объекта и использовать this keyword для определения свойства и методов. Ниже приведен пример.

// 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
0 голосов
/ 30 сентября 2015

В большинстве случаев вам нужно как-то объявить необходимое свойство, прежде чем вы сможете вызвать метод, передающий эту информацию. Если вам не нужно изначально устанавливать свойство, вы можете просто вызвать метод внутри объекта следующим образом. Вероятно, не самый красивый способ сделать это, но это все еще работает.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
0 голосов
/ 19 августа 2014

просто чтобы предложить немного разнообразия. ds.oop - это хороший способ объявить классы с конструкторами в javascript. Он поддерживает все возможные типы наследования (включая 1 тип, который даже не поддерживает c #), а также интерфейсы, что приятно.

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 голосов
/ 18 августа 2014

http://www.jsoops.net/ вполне достаточно для упс в Js. Если предоставить частную, защищенную, публичную переменную и функцию, а также функцию наследования. Пример кода:

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 голосов
/ 01 ноября 2013

При использовании большого шаблона Blixt, описанного выше, я обнаружил, что он не очень хорошо работает с многоуровневым наследованием (MyGrandChildClass, расширяющий MyChildClass, расширяющий MyClass) - он циклически вызывает конструктор первого родителя снова и снова. Итак, вот простой обходной путь - если вам нужно многоуровневое наследование, вместо использования this.constructor.super.call(this, surName); используйте chainSuper(this).call(this, surName); с функцией цепочки, определенной следующим образом:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...