Какие методы можно использовать для определения класса в JavaScript, и каковы их компромиссы? - PullRequest
679 голосов
/ 23 декабря 2008

Я предпочитаю использовать ООП в крупных проектах, таких как тот, над которым я сейчас работаю. Мне нужно создать несколько классов в JavaScript, но, если я не ошибаюсь, есть по крайней мере несколько способов сделать это. Каков будет синтаксис и почему это будет сделано таким образом?

Я бы хотел избежать использования сторонних библиотек - по крайней мере, сначала.
В поисках других ответов я нашел статью Объектно-ориентированное программирование на JavaScript, часть I: Наследование - Doc JavaScript , в которой обсуждается объектно-ориентированное программирование на JavaScript. Есть ли лучший способ сделать наследство?

Ответы [ 19 ]

10 голосов
/ 23 декабря 2008

Простой способ:

function Foo(a) {
  var that=this;

  function privateMethod() { .. }

  // public methods
  that.add = function(b) {
    return a + b;
  };
  that.avg = function(b) {
    return that.add(b) / 2; // calling another public method
  };
}

var x = new Foo(10);
alert(x.add(2)); // 12
alert(x.avg(20)); // 15

Причина that заключается в том, что this может быть привязан к чему-то другому, если вы зададите метод в качестве обработчика событий, поэтому вы сохраняете значение во время его создания и используете его позже.

Изменить: это определенно не лучший способ, просто простой способ. Я тоже жду хороших ответов!

9 голосов
/ 07 апреля 2013

Вы, вероятно, хотите создать тип, используя шаблон сворачивания:

    // Here is the constructor section.
    var myType = function () {
        var N = {}, // Enclosed (private) members are here.
            X = this; // Exposed (public) members are here.

        (function ENCLOSED_FIELDS() {
            N.toggle = false;
            N.text = '';
        }());

        (function EXPOSED_FIELDS() {
            X.count = 0;
            X.numbers = [1, 2, 3];
        }());

        // The properties below have access to the enclosed fields.
        // Careful with functions exposed within the closure of the
        // constructor, each new instance will have it's own copy.
        (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
            Object.defineProperty(X, 'toggle', {
                get: function () {
                    var before = N.toggle;
                    N.toggle = !N.toggle;
                    return before;
                }
            });

            Object.defineProperty(X, 'text', {
                get: function () {
                    return N.text;
                },
                set: function (value) {
                    N.text = value;
                }
            });
        }());
    };

    // Here is the prototype section.
    (function PROTOTYPE() {
        var P = myType.prototype;

        (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
            Object.defineProperty(P, 'numberLength', {
                get: function () {
                    return this.numbers.length;
                }
            });
        }());

        (function EXPOSED_METHODS() {
            P.incrementNumbersByCount = function () {
                var i;
                for (i = 0; i < this.numbers.length; i++) {
                    this.numbers[i] += this.count;
                }
            };
            P.tweak = function () {
                if (this.toggle) {
                    this.count++;
                }
                this.text = 'tweaked';
            };
        }());
    }());

Этот код даст вам тип с именем myType . Он будет иметь внутренние закрытые поля с именами toggle и text . Он также будет иметь этих открытых членов: поля count и numbers ; свойства toggle , text и numberLength ; методы incrementNumbersByCount и твик .

Шаблон складывания подробно описан здесь: Javascript Folding Pattern

3 голосов
/ 16 августа 2016

Код гольфа для @ liammclennan's ответа .

var Animal = function (args) {
  return {
    name: args.name,

    getName: function () {
      return this.name; // member access
    },

    callGetName: function () {
      return this.getName(); // method call
    }
  };
};

var cat = Animal({ name: 'tiger' });
console.log(cat.callGetName());
2 голосов
/ 02 февраля 2016

Классы на основе объектов с наследованием

var baseObject = 
{
     // Replication / Constructor function
     new : function(){
         return Object.create(this);   
     },

    aProperty : null,
    aMethod : function(param){
      alert("Heres your " + param + "!");
    },
}


newObject = baseObject.new();
newObject.aProperty = "Hello";

anotherObject = Object.create(baseObject); 
anotherObject.aProperty = "There";

console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null

Просто, сладко, и готово.

2 голосов
/ 30 мая 2009

MooTools (Мой объектно-ориентированный инструментарий) основан на идее классов . Вы даже можете расширить и реализовать с наследованием.

Когда освоено, это делает смехотворно многократно, мощный javascript.

1 голос
/ 23 августа 2017

На примере Триптиха это может быть даже проще:

    // Define a class and instantiate it
    var ThePerson = new function Person(name, gender) {
        // Add class data members
        this.name = name;
        this.gender = gender;
        // Add class methods
        this.hello = function () { alert('Hello, this is ' + this.name); }
    }("Bob", "M"); // this instantiates the 'new' object

    // Use the object
    ThePerson.hello(); // alerts "Hello, this is Bob"

Это создает только один экземпляр объекта, но все еще полезно, если вы хотите инкапсулировать кучу имен для переменных и методов в классе. Обычно в конструкторе не было бы аргументов «Bob, M», например, если методы были бы вызовами системы с ее собственными данными, такими как база данных или сеть.

Я все еще слишком плохо знаком с JS, чтобы понять, почему он не использует prototype.

1 голос
/ 18 июля 2017

База

function Base(kind) {
    this.kind = kind;
}

А класс

// Shared var
var _greeting;

(function _init() {
    Class.prototype = new Base();
    Class.prototype.constructor = Class;
    Class.prototype.log = function() { _log.apply(this, arguments); }
    _greeting = "Good afternoon!";
})();

function Class(name, kind) {
    Base.call(this, kind);
    this.name = name;
}

// Shared function
function _log() {
    console.log(_greeting + " Me name is " + this.name + " and I'm a " + this.kind);
}

Действие

var c = new Class("Joe", "Object");
c.log(); // "Good afternoon! Me name is Joe and I'm a Object"
0 голосов
/ 13 сентября 2018

//new way using this and new
function Persons(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

var gee=new Persons("gee");
gee.greeting();

var gray=new Persons("gray");
gray.greeting();

//old way
function createPerson(name){
 var obj={};
 obj.name=name;
 obj.greeting = function(){
 console.log("hello I am"+obj.name);
 }; 
  return obj;
}

var gita=createPerson('Gita');
gita.greeting();
0 голосов
/ 23 декабря 2008

JavaScript является объектно-ориентированным , но он радикально отличается от других OOP языков, таких как Java, C # или C ++. Не пытайтесь понять это так. Выкинь это старое знание и начни заново. JavaScript нуждается в другом мышлении.

Я бы посоветовал получить хорошее руководство или что-нибудь по этому вопросу. Я сам нашел Учебники по ExtJS для меня лучше всего, хотя я не использовал фреймворк ни до, ни после прочтения. Но это дает хорошее объяснение того, что есть в мире JavaScript. Извините, похоже, что этот контент был удален. Вот ссылка на archive.org вместо . Работает сегодня. : P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...