javascript: создайте новый безопасный конструктор класса - PullRequest
2 голосов
/ 25 декабря 2010

иногда мы теряем новое ключевое слово при определении нового объекта,

obj = new Clazz(); //correct
obj = Clazz(); //wrong, but no syntax error, hard to debug.

Я хочу написать функцию, которая поможет мне создать класс и сделать его новым безопасным.

var Class = function(){
   var constructor = arguments[0];
   var superClasses = arguments[1..n];
   function clazz(){
     if(! this instanceof clazz){
         return new clazz()//pass clazz arguments,not Class arguments
     }
     constructor();//pass clazz arguments
   }

   //clazz inherit from superClasses 

   return clazz;
}

var MyClazz = Class(function(name){
    this.name = name
}, SuperClazz1, SuperClass2 )

MyClazz.extend({
    show: function(){console.log(this.name)}
})

obj1 = new MyClazz("name1"); 
obj2 = MyClazz("name2");
// obj1 should same as obj2

Возможно, существует какой-либо модуль?

Ответы [ 2 ]

3 голосов
/ 25 декабря 2010

иногда мы теряем новое ключевое слово ...

Все о дисциплине кодирования и тестировании ... в любом случае, перейдем к вашему вопросу.

Чтобы узнатьесли ваша функция была вызвана как конструктор, используйте instanceof:

function Foo() {
    console.log(this instanceof Foo);
}

Foo();  // false
new Foo(); // true

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

Обновление

Передача аргументов переменной конструктору невозможна,new clas.call(....) приведет к ошибке, что call не является конструктором.

Вы можете сделать две вещи:

  1. Вместо возврата самой функции Class из фабрики классовметод, возвращает функцию, которая создает новый экземпляр, устанавливает все необходимые вещи, а затем возвращает этот экземпляр (это усложнит наследование)
  2. Просто используйте ключевое слово new.

Я написал свой собственный Class thingy , и я пытался поддерживать синтаксис new и () для создания экземпляров.Весь материал наследования и т. Д. Достаточно сложен, что делает его еще более волшебным только для того, чтобы сэкономить 4 больше символов ... не стоит усилий.Используйте new и пишите тесты.

Еще одно обновление

ОК Я не удержался, чтобы взломать больше, и заставил его работать:

function is(type, obj) {
    return Object.prototype.toString.call(obj).slice(8, -1) === type;
}

function clas(args) {
    if (is('Object', this)) {
        ctor.apply(this, is('Arguments', args) ? args : arguments);

    } else {
        return new clas(arguments);
    }
}

Это сделает магию, по крайней мере, в моем случае.

1 голос
/ 23 мая 2011

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

Мое решение вы можете увидеть здесь: http://mikepackdev.com/blog_posts/9-new-scope-safe-constructors-in-oo-javascript

Надеюсь, это поможет!

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