Javascript OO синтаксис - PullRequest
       2

Javascript OO синтаксис

6 голосов
/ 16 сентября 2010

Кажется, есть много разных способов сделать ОО в JavaScript.

Мне нравится:

function ClassA(){};
ClassA.prototype={
    someFunc:function(a,b,c){},
    otherFunc:function(){}
}
var c=new ClassA();

и никогда не использовал функции сверх того, что это обеспечивает (несмотря на то, что он опытный специалист). Я подозреваю, что это старомодно, потому что очень часто я вижу новые блестящие варианты, и это заставляет меня задуматься, выбираю ли я лучший подход. Например, вы можете использовать магию в методе конструктора для создания закрытых переменных и методов доступа, что я считал (до относительно недавнего времени) невозможным. Как насчет подклассов? Я не знаю, как этого добиться, но сейчас у него должна быть какая-то общая схема.

Как ты это делаешь и почему?

Ответы [ 7 ]

6 голосов
/ 16 сентября 2010
function foo() {
  var bar = function() { console.log("i'm a private method"); return 1; };
  var iAmAPrivateVariable = 1;

  return {
    publicMethod: function() { alert(iAmAPrivateVariable); },
    publicVariable: bar()
  }
}

//usage
var thing = foo()

Это известно как функциональный подход, так как вы фактически используете замыкания для инкапсуляции (это единственный способ сделать это в javascript).

В общем случае вам не следуетделать ОО в javascript, это не так уж хорошо для этого языка по многим причинам.Придумайте схему с волнистыми скобками и точками с запятой, и вы начнете писать язык, как это делают профессионалы.Тем не менее, иногда ОО лучше подходит.В этих случаях вышеописанное, как правило, является лучшей ставкой

РЕДАКТИРОВАТЬ: внести наследование в микс

function parent() {
  return { parentVariable: 2 };
}

function foo() {
  var bar = function() { console.log("i'm a private method"); return 1; };
  var iAmAPrivateVariable = 1;

  me = parent();
  me.publicMethod = function() { alert(iAmAPrivateVariable); };
  me.publicVariable = bar();

  return me;
}

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

EDIT2:

Просто хотел отдать должное, когда это необходимо, этот подход является очень небольшим упрощением того, что предлагает Даг Крокфорд в Javascript: The Good Parts.Если вы хотите поднять свои навыки js на следующий уровень, я настоятельно рекомендую начать там.Я не думаю, что когда-либо узнал так много из такой маленькой книги.

Еще одно замечание: это сильно отличается от того, что вы будете видеть большую часть времени на большинстве работ, над которыми вы когда-либо будете работать,и часто очень трудно объяснить а) что происходит, и б) почему это хорошая идея для коллег.

5 голосов
/ 16 сентября 2010

Простое наследование JavaScript

Потому что Джон Ресиг так сказал.

2 голосов
/ 16 сентября 2010

«Подклассификация» в JavaScript обычно относится к наследованию на основе прототипов, которое в основном следует этому шаблону:

function Superclass() { }
Superclass.prototype.someFunc = function() { };

function Subclass() { }
Subclass.prototype = new Superclass();
Subclass.prototype.anotherFunc = function() { };

var obj = new Subclass();

Это создает "цепочку прототипов" из obj -> Subclass.prototype -> Superclass.prototype -> Object.prototype.

Практически каждая библиотека ООП для JavaScript основана на этом методе, предоставляя функции, которые абстрагируют большую часть прототипа от "магии".

1 голос
/ 16 сентября 2010

Объекты в JavaScript отличаются от почти всех других громких языков.Вместо на основе классов (как в Java, C ++, PHP и т. Д.) Они основаны на прототипах .Таким образом, базовая парадигма объектно-ориентированного программирования должна быть значительно изменена.Люди, которые не могут или не хотят переосмыслить это и настаивают на использовании мышления на основе классов, должны строить логику на основе классов в JavaScript или использовать код от кого-то, кто уже его создал.

1 голос
/ 16 сентября 2010

Я думаю, что Joose - довольно крутой способ сделать ООП в JavaScripthttp://code.google.com/p/joose-js/

0 голосов
/ 16 июля 2015

ООП в Javascript для Холста

Проверьте, насколько полезным может быть ООП в js в другой ситуации ... Это позволяет вам рисовать квадраты и круги as objects, чтобы вы могли вернуться назад и повторить цикл или манипулировать ими, как вам нравится.

function Shape(x,y,color){
  this.x = x
  this.y = y
  this.color = color
}

function Square(height,width,color){
  Shape.call(this, event.x, event.y, color)
  this.height = height
  this.width = width
  this.x -= canvas.offsetLeft + (this.height/2)
  this.y -= canvas.offsetTop + (this.width/2)
}

Square.prototype = new Shape();
Square.prototype.draw = function(color){
  ctx.fillStyle = color
  ctx.fillRect(this.x,this.y,this.height,this.width)
}

function Circle(color, width){
  Shape.call(this)
  this.x = event.x -60
  this.y = event.y -60
  this.width = width
 }

Circle.prototype = new Shape();
Circle.prototype.draw = function(color){
  ctx.beginPath()
  ctx.arc(this.x,this.y,this.width,0,2*Math.PI, false);
  ctx.fillStyle = color
  ctx.fill()
}
0 голосов
/ 16 сентября 2010

Мне нравится делать что-то вроде

// namespace "My"
var My = new function {

  // private methods
  /**
   * Create a unique empty function.
   * @return {Function} function(){}
   */
  function createFn () {return function(){}}

  /** A reusable empty function. */
  function emptyFn () {}

  /**
   * Clone an object
   * @param {Object}  obj     Object to clone
   * @return {Object}         Cloned object
   */
  function clone (obj) { emptyFn.prototype=obj; return new emptyFn() }

  // public methods
  /**
   * Merge two objects
   * @param {Object} dst        Destination object
   * @param {Object} src        Source object
   * @param {Object} [options]  Optional settings
   * @return {Object}           Destination object
   */
  this.merge = function (dst, src, options) {
    if (!options) options={};
    for (var p in src) if (src.hasOwnProperty(p)) {
      var isDef=dst.hasOwnProperty(p);
      if ((options.noPrivate && p.charAt(0)=='_') || 
          (options.soft && isDef) || 
          (options.update && !isDef)) continue;
      dst[p]=src[p]; 
    }
    return dst;
  }

  /**
   * Extend a constructor with a subtype
   * @param {Function} superCtor      Constructor of supertype
   * @param {Function} subCtor        Constructor of subtype
   * @param {Object} [options]        Optional settings
   * @return {Function}               Constructor of subtype
   */
  this.extend = function (superCtor, subCtor, options) {
    if (!subCtor) subCtor=createFn();
    if (!options) options={};
    if (!options.noStatic) this.merge(subCtor, superCtor, options); 
    var oldProto=subCtor.prototype;
    subCtor.prototype=clone(superCtor.prototype);
    this.merge(subCtor.prototype, oldProto);
    if (!options.noCtor) subCtor.prototype.constructor=subCtor; 
    return subCtor;
  }

}

А потом что-то вроде ...

// namespace "My.CoolApp"
My.CoolApp = new function(){

  // My.CoolApp.ClassA
  this.ClassA = new function(){

    // ClassA private static
    var count=0; 

    // ClassA constructor 
    function ClassA (arg1) {
      count++;
      this.someParam=arg1;
    }

    // ClassA public static
    My.merge(ClassA, { 
      create: function (arg1) {
        return new ClassA(arg1);
      }
    }

    // ClassA public
    My.merge(ClassA.prototype, {
      doStuff : function (arg1) {
        alert('Doing stuff with ' + arg1);
      },
      doOtherStuff : function (arg1) {
        alert('Doing other stuff with ' + arg1);
      }
    }

    return ClassA;
  }

  // My.CoolApp.ClassB
  this.ClassB = new function(){

    My.extend(My.CoolApp.ClassA, ClassB);
    // ClassB constructor
    function ClassB () {
      ClassA.apply(this, arguments);
    }

    return ClassB;
  }

}

... функция clone является ключом к наследованию.Вкратце:

  • Клонируйте объект, сделав его прототипом одноразовой функции и вызвав функцию с помощью 'new'.
  • Клонируйте прототип родительского конструктора и установите его результаткак прототип дочернего класса.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...