Подтвердить что ты не робот

Псевдо-классический вариант "Метод JavaScript"

Только что закончил читать Crockford " JavaScript: хорошие части", и у меня есть вопрос относительно его позиции в отношении psuedo-classic против прототипных подходов. На самом деле меня это совсем не интересует его позиция; Я просто хочу понять его аргумент, чтобы я мог установить свою собственную позицию.

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

Я думал, что понял, откуда он, но я думаю, что нет.

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

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" был человеком, что бы она предложила?

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

4b9b3361

Ответ 1

Смотрите: Является ли JavaScript "новым" ключевым словом считается вредным?

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

Ответ 2

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

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

Ответ 3

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

Метод, более подходящий для 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");

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

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

Ответ 4

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

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

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