Псевдоклассика против «пути JavaScript» - PullRequest
18 голосов
/ 26 апреля 2009

Только что закончил читать Крокфорда " JavaScript: The Good Parts ", и у меня есть вопрос, касающийся его позиции по отношению к псевдоклассическому и прототипному подходам. На самом деле меня не очень интересует его позиция; Я просто хочу понять его аргумент, чтобы я мог выработать собственную позицию.

В книге Крокфорд, по-видимому, делает вывод о том, что функции конструктора и «весь этот джаз» не должен использоваться в JavaScript, он упоминает, как плохо реализовано ключевое слово «new» - то есть неконструкторные функции можно вызывать с помощью ключевое слово 'new' и наоборот (потенциально вызывающее проблемы).

Мне показалось, что я понял, откуда он, но, думаю, нет.

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

function MyModule(something) {
    this.something = something || {};
}

А потом я бы добавил несколько методов к его прототипу:

MyModule.prototype = {
    setSomething : function(){},
    getSomething : function(){},
    doSomething : function(){}
}

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

var foo = new MyModule({option1: 'bar'});
// Foo is an object; I can do anything to it; all methods of the "class"
// are available to this instance.

У меня вопрос : Как мне достичь вышеуказанного, используя подход, более подходящий для JavaScript? Другими словами, если бы «JavaScript» был человеком, что бы она предложила?

Также: что означает Крокфорд, когда говорит, что определенный шаблон дизайна «более выразителен», чем другой?

Ответы [ 4 ]

10 голосов
/ 26 апреля 2009

См .: Считает ли «новое» ключевое слово JavaScript вредным?

Важно помнить, что Крокфорд, как и многие другие программисты на JavaScript, сначала подошел к языку, стараясь «исправить» его - сделав его более похожим на другие (так называемые «классические») ОО-языки. Поэтому было написано большое количество структурного кода, построены библиотеки и фреймворки, и ... потом они начали понимать, что в этом нет необходимости; если вы подойдете к JS на его собственных условиях, вы можете отлично ладить.

4 голосов
/ 26 апреля 2009

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

Object.beget = function (o) { /* Crockfords replacement for the new */ }

var myModule = {
    something : null,
    getSomething : function () {},
    setSomething : function () {},
    doSomething : function () {}
};

И тогда вы можете сделать:

var foo = Object.beget(myModule);
foo.something = bar;

ОБНОВЛЕНИЕ: Вы также можете использовать шаблон построителя для замены конструктора следующим образом:

var myModuleBuilder = {
    buildMyModule : function (something) {
        var m = Object.beget(myModule);
        m.something = something || {};
        return m;
    }
}

так что вы можете сделать:

var foo = myModuleBuilder.buildMyModule(something);
2 голосов
/ 26 апреля 2009

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

Метод, более подходящий для Javascript:

var MyClass = function (storeThis) {
 this.storage = storeThis
}

MyClass.prototype.getStorage = function (){
   return this.storage;
}

MyClass.prototype.setStorage = function (newStorage){
  this.storage = newStorage;
}

Используйте это:

var myInstance = new MyClass("sup");
alert("myInstance storage: " + myInstance.getStorage());
myInstance.setStroage("something else");

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

И когда кто-то говорит что-то, например шаблон проектирования, более «выразительно», он или она обычно подразумевают, что шаблон проектирования понятен и прост для понимания того, чего он добивается и как.

0 голосов
/ 03 августа 2014

Javascript не человек, поэтому она не может предложить, что вы делаете.

Ни в одном из приведенных выше ответов не упоминается простой старый функциональный стиль наследования, который я склоняюсь к простейшему.

function myModuleMaker(someProperty){
  var module = {}; //define your new instance manually

  module.property = someProperty; //set your properties

  module.methodOne = function(someExternalArgument){
    //do stuff to module.property, which you can, since you have closure scope access
  return module;
  }
}

Теперь, чтобы создать новый экземпляр:

var newModule = myModuleMaker(someProperty);

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

Я думаю, что трудно утверждать, что любой из этих методов сам по себе является "плохой практикой".

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