Конструкторы в объектах JavaScript

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

11.07.2009 16:11:42
19 ОТВЕТОВ
РЕШЕНИЕ

Использование прототипов:

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

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

Сокрытие «color» (чем-то напоминает приватную переменную-член):

function Box(col)
{
   var color = col;

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

Применение:

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

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
408
18.11.2015 16:34:00
@BorisB, да, вы делаете - это определяет цвет и getColor для объекта Box, в противном случае вы назначаете переменные в обычной области видимости.
Nick 15.06.2012 16:23:47
@ Джич, да, это так. Я предоставил альтернативный фрагмент, который скрывается color. Я бы предположил, что вы используете в значительной степени зависит от личных предпочтений (защита против простоты)
Nick 24.06.2012 12:43:20
@CamiloMartin Хотя это не всегда необходимо, создание переменной «private» (или, в данном случае, безымянной) может быть полезным способом предотвращения зависимости внешнего кода от деталей реализации вашего класса. Даже просто указание того, какие элементы класса являются публичными / частными, может быть полезным для внешних пользователей.
Nick 18.09.2012 21:39:45
varделает приватную переменную. thisделает публичную переменную
EhevuTov 29.09.2012 16:09:14
@AlanKis (по крайней мере, в некоторых движках Javascript) трассировка стека в случае анонимной функции даже не упоминается Foo, тогда как в последнем случае она будет знать, что она Fooвызывается. Очень полезно для отладки.
Joachim Isaksson 21.10.2013 11:36:09

Вот шаблон, который я иногда использую для ООП-подобного поведения в JavaScript. Как видите, вы можете моделировать частные (как статические, так и экземпляры) члены, используя замыкания. То, new MyClass()что вернётся, это объект с только свойствами, назначенными thisобъекту и prototypeобъекту «класса».

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

Меня спросили о наследовании с использованием этого шаблона, поэтому здесь идет:

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

И пример, чтобы использовать все это:

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

Как видите, классы корректно взаимодействуют друг с другом (они имеют статический идентификатор MyClass, announceметод использует правильный get_nameметод и т. Д.)

Стоит отметить, что необходимо скрывать свойства экземпляра. Вы можете заставить inheritфункцию пройти через все свойства экземпляра (используя hasOwnProperty), которые являются функциями, и автоматически добавить super_<method name>свойство. Это позволит вам вызывать this.super_get_name()вместо того, чтобы хранить его во временном значении и вызывать его с помощью call.

Для методов в прототипе вам не нужно беспокоиться о вышеупомянутом, хотя, если вы хотите получить доступ к методам прототипа суперкласса, вы можете просто вызвать this.constructor.super.prototype.methodName. Если вы хотите сделать его менее подробным, вы, конечно, можете добавить удобные свойства. :)

248
27.11.2012 18:35:28
Просто примечание о cls.prototypeчасти: «общий доступ к экземплярам» предназначен только для чтения значения (вызова announce). Если вы установите myClassInstance.announceдругое значение, оно создаст новое свойство myClassInstance, поэтому оно будет применяться только к этому объекту, а не к другим экземплярам класса. Назначение MyClass.prototype.announceбудет влиять на все экземпляры, хотя.
Matthew Crumley 11.07.2009 18:55:38
Нет проблем, рад помочь! :)
Blixt 20.07.2011 18:50:54
Спасибо! Очень понравилось! Не могли бы вы показать пример наследования классов в этом подходе.
Dmitrij Golubev 15.10.2012 11:29:42
@DmitrijGolubev, Брэд Дуайер и Натан С. Треш: Я добавил наследование, но оно становится довольно сложным, поэтому я обычно советую вам перейти к более простому решению, если вам не нужно такое жесткое наследование в JavaScript (которое на самом деле просто прототип языка).
Blixt 27.11.2012 18:37:17
@guiomie Это «публичный статический» метод, поэтому вы должны вызывать его для функции конструктора («класс»), а не для экземпляра:MyClass.get_nextId()
Blixt 28.05.2014 22:34:55

Так в чем же смысл свойства "конструктор"? Не можете понять, где это может быть полезно, какие-либо идеи?

Смысл свойства конструктора состоит в том, чтобы обеспечить некоторый способ притворяться, что JavaScript имеет классы. Одна из вещей, которую вы не можете сделать, это изменить конструктор объекта после того, как он был создан. Это сложно.

Я написал довольно обширную статью об этом несколько лет назад: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

23
13.03.2011 22:16:41
Дело в том, чтобы использовать ключевое слово «новый». «d = new Drofto ()» создает пустой объект и запускает функцию Drofto с указанным новым объектом, ограниченным как «this». Функция Drofto может возвращать что угодно, но обычно возвращается что-то, что считается членом класса Drofto.
Juan Lanus 17.12.2014 12:47:56

Используя приведенный выше пример Ника, вы можете создать конструктор для объектов без параметров, используя оператор return в качестве последнего оператора в определении вашего объекта. Верните функцию конструктора, как показано ниже, и она будет запускать код в __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();
4
19.03.2012 11:07:36
Вы не возвращаете функцию конструктора, вы просто вызываете ее.
David Conrad 6.06.2013 16:55:31
Если вы попытаетесь использовать this.getColor();в строке выше, alert("Object Created.");ничего не будет предупреждено. Там будет ошибка, как «getColor не определен». Если вы хотите, чтобы construct мог вызывать другие методы объекта, его необходимо определить после всех других методов. Поэтому вместо вызова __construct();последней строки просто определите конструкцию там и поставьте ()после нее, чтобы принудительно выполнить ее автоматически.
thinsoldier 13.06.2013 17:14:35
Коррекция. Добавление ()в конец определения __construct все равно привело к ошибке. Мне пришлось звонить __construct();по собственной линии, как в оригинальном коде, чтобы избежать ошибки.
thinsoldier 13.06.2013 17:28:37

Это конструктор:

function MyClass() {}

Когда вы делаете

var myObj = new MyClass();

MyClass выполняется, и возвращается новый объект этого класса.

10
25.05.2013 04:24:01
Чтобы уточнить, что это означает, вы можете сказать, что это наверху вашего класса, alert(valuePassedInAsArgument);и это будет выполняться один раз для каждого экземпляра, поэтому весь класс является самим конструктором.
Martin Lyne 8.11.2012 15:19:00
new object is returned of that class- разве это не похоже на возвращение нового объекта этой функции?
Don Cheadle 24.07.2015 15:53:01
в JavaScript функции являются объектами
Leo 27.04.2016 16:49:46

Я предполагаю, что я отправлю то, что я делаю с закрытием javascript, так как никто еще не использует закрытие.

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

Комментарии и предложения к этому решению приветствуются. :)

6
1.06.2012 01:56:23
Пара комментариев: 1) утверждение, если (! Id) небезопасно, значения, такие как 0 или ложь, приведут к тому, что он оценит истину и вернет ноль. Я предполагаю, что вы хотите проверить наличие неопределенного или нулевого значения, в этом случае === пустое значение и === неопределенное будет лучше. 2) Это больше напоминает шаблон модуля ( адекватноgood.com /2010/3/ JavaScript-Module-Pattern- In-Depth ) в сравнении с конструктором, отличие состоит в том, что модуль возвращает объект из функции, тогда как конструктор создает объект, когда в паре с новым ключевым словом, и в этом случае вы будете устанавливать значения «this» вместо объекта.
Rich 25.02.2013 20:30:44

Мне кажется, что большинство из вас приводит пример геттеров и сеттеров, а не конструкторов, т.е. http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

Ланч-дан был ближе, но пример не работал в jsFiddle.

В этом примере создается функция частного конструктора, которая запускается только во время создания объекта.

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

Если вы хотите назначить открытые свойства, тогда конструктор можно определить так:

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
166
14.12.2013 01:53:22
Как это не ответ № 1? Только Джон создал конструктор с параметрами.
Rap 30.08.2012 14:29:43
Есть ли способ получить пример наследования, используя эту парадигму для конструкторов?
Nathan C. Tresch 26.11.2012 22:26:14
@Rap Пример конструктора Джона не имеет параметров, так как это Box()функция :). Но этот пример, а также примеры в других ответах могут быть легко расширены для принятия параметров.
Alexander Stepaniuk 31.12.2012 18:28:19
@AndersonGreen вы можете добавить параметр в Box, а затем передать его частному конструктору в качестве параметра функции.
Gautham C. 12.08.2013 16:22:06
Там нет необходимости для "частных конструкторов". Просто сделайте свою конструкцию в Boxфункции, и вы готовы (это все еще "личное"). «Приватный» в Javascript означает просто доступ через лексическую область; нет необходимости назначать членам. Дополнительно: этот код неверен. Это создает глобальную __constructпеременную, что довольно плохо. varследует использовать для ограничения сферы действия __construct.
mattbasta 15.11.2013 01:41:45

Эта модель хорошо послужила мне. С помощью этого шаблона вы создаете классы в отдельных файлах, загружая их в ваше общее приложение «по мере необходимости».

// 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");
8
13.01.2016 14:04:16
Это переменные экземпляра, но они имеют «общедоступную» доступность, а не «приватную», как в C ++ или Java.
Potatoswatter 7.12.2012 16:05:11
Как бы вы создали частную переменную (в классическом смысле), относящуюся к экземпляру, но не общую для всех экземпляров?
bob 9.01.2013 08:31:16
Смотрите сайт Дугласа Крокфорда , он один из языковых дизайнеров и выдающийся авторитет. Я не всегда следую его шаблонам, но в целом частная переменная является локальной varв конструкторе (или аргумент функции, или в функции, подобной конструктору).
Potatoswatter 9.01.2013 08:34:57
Спасибо за совет ... следующая страница объясняет, что я искал: javascript.crockford.com/private.html
bob 9.01.2013 08:53:41
Ой, извините за то, что не протестировал ссылку: P
Potatoswatter 9.01.2013 09:40:22

Я нашел этот урок очень полезным. Этот подход используется большинством плагинов 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;    
};

Сейчас же ,

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]"
8
15.05.2013 14:42:22
Я съеживаюсь всякий раз, когда вижу, что люди используютklass
Madbreaks 31.05.2013 21:24:46

Пример здесь: http://jsfiddle.net/FZ5nC/

Попробуйте этот шаблон:

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

Вы должны настроить свое пространство имен, если вы определяете статический класс:

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

Пример класса:

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

Пример реализации:

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

Функции уведомления определяются как AB = function A_B (). Это должно облегчить отладку вашего скрипта. Откройте панель проверки элемента Chrome, запустите этот скрипт и разверните трассировку отладки:

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

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

Fail.Test();
</script>
16
30.09.2013 00:24:21
Пример добавлен. Также добавлена ​​информация по улучшению вывода отладки.
bitlather 26.05.2013 02:21:02
Возможно, потому что это добавляет ненужный уровень сложности к проблеме. Трудно найти ответ в своем посте из-за педантичного расстояния между именами и статического объявления класса. Не поймите меня неправильно, это хорошая информация, но она, безусловно, более запутанная, чем полезная, если вы пытаетесь проникнуть в дверь понимания. Я на полпути компетентен в JS, и я едва понимаю, что ты здесь делаешь, или почему это имеет отношение к "Как мне конструктор?"
Bmo 20.09.2013 18:28:11
Спасибо за понимание, БМО. Это был длинный пост, но это потому, что я не понимаю, как использовать конструктор, если он не привязан к четко определенному объекту и реализации статического класса. При изучении C ++ или Java вы должны научиться реализовывать классы вместе с конструкторами. С тех пор, как я наткнулся на этот метод написания javascript, веб-разработчик стал намного приятнее, и я просто хотел поделиться им. Я переместил скрипку наверх, чтобы ее было легче найти. Я надеюсь, что это прояснит любую путаницу.
bitlather 30.09.2013 00:23:06
@Bmo Вы серьезно относитесь к тому, что две строки о пространстве имен затрудняют поиск конструктора точно ниже, особенно с учетом комментария «Конструктор» - ДОЛЖЕН БЫТЬ НА ТОП ФАЙЛА? Предоставление примера с пространством имен очень приветствуется, сообщество разработчиков javascript слепо игнорирует пространства имен, вызывая трудности при обнаружении ошибок при столкновении имен. Грустно видеть, что js devs думают, копируют ли они текст из поста в Интернете и делают что-то похожее на то, что им нужно, их работа завершена.
user3285954 1.01.2015 13:28:27
Основная проблема с js и веб-разработкой в ​​целом заключается в том, что большинство разработчиков игнорируют все практики, которые создавала индустрия за 50 с лишним лет, и думают, что если они смогут сделать вызов ajax, то они - король. Так грустно видеть, что потребовалось много лет, чтобы начать использовать хорошо известные шаблоны и практики в javascript.
user3285954 1.01.2015 13:30:32

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

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
1.11.2013 07:48:01

Они делают, если вы используете 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;
})();
3
23.05.2014 02:20:15
Я работаю над большим проектом и пытаюсь убедить людей в том, что TypeScript поможет нам быстро пробежаться. Посмотрим, как это будет.
wootscootinboogie 23.05.2014 12:29:11
@wootscootinboogie За один день (заканчивающийся в 5:30 прямо сейчас) я довольно далеко и довольно комфортно с ним. Я настоятельно рекомендую прочитать спецификацию до конца, и хотя вы можете пропустить половину реальных мелочей, вы делаете себе одолжение, прочитав его хотя бы один раз. видео этого парня отлично youtube.com/user/basaratali/videos . удачи)
Simon_Weaver 23.05.2014 12:31:36

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
18.08.2014 16:35:32

просто чтобы предложить немного разнообразия. 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
19.08.2014 18:50:41

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

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
-2
30.09.2015 13:33:21

В 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

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

1
2.05.2016 11:43:08

Да, вы можете определить конструктор внутри объявления класса следующим образом:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
8
2.05.2016 13:43:25
для версии IE> 12
zloctb 22.07.2016 06:49:17
Bruno 9.08.2016 12:22:54
Это единственный фактический ответ на вопрос. : /
MarcD 14.05.2018 10:05:51

Может быть, это стало немного проще, но вот то, что я придумал сейчас в 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
9.08.2017 15:25:22

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

// 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
27.09.2017 18:39:09