powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / покритикуйте пожалуйста
7 сообщений из 7, страница 1 из 1
покритикуйте пожалуйста
    #38521141
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рядом конечно уже есть моя тема, где ведётся подобное обсуждение. Но там как-то много слов получилось. А сейчас уже вроде есть более-менее полноценный код, вот именно его я и хотел бы обсудить.

Итак, идея была в реализации простого наследования в js, проверки аргументов функций на валидность (жёсткая типизация), а как следствие возможность реализации перегрузки методов. Основной упор делался на последнее, так как этого мне больше всего не хватает в js.

Итак, добился работоспособности такого кода:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
function MyTestObject(){
  this.ext(TObject, []);
  
  this.__(['String', 'Number'], function try2(a1, a2){
   return a1+a2;
  });
  
  this.__(['String'], function try2(a1){
     return a1;
  });
  
  this._(['Number'], function onlyValidate(num){
     return num*2;
  })
}

var t = new MyTestObject();
alert(t.try2('hello'));
alert(t.try2('hello', 10));
alert(t.onlyValidate(8));
t.try2(1, 2);



Основной вопрос, кто считает это удобным, кто не считает таковым... Если не удобно, то почему и как бы сделать лучше (не отходя от стандартного синтаксиса js, что бы проверка синтаксиса привычной IDE не заканчивалось провалом)?

А вот сама реализация (может по ней будут какие-то дополнения, пока не комментировал ничего, уже просто спать немного охота, завтра буду облагораживать код):

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
Object.prototype.ext = function(construct, args){
  construct.apply(this, args);
  this._prototypes.push(construct);
}

Object.prototype.instanceOf = function(className){
  if(this.constructor.name===className) return true;
  if(typeof(this._prototypes)==='undefined') return false;
  var res = false;
  for(var i=0; i<this._prototypes.length; i++){
    if(this._prototypes[i].name===className){
      res=true;
      break;
    }
  }
  return res;
}

Object.prototype._ = function(types, func){
  var obj = this;
  this[func.name] = function(){
    var err = TypeError();
    var trace = err.stack.split("\n").slice(3).join("\n");
    if(arguments.length<types.length){
      err.message = 'too few arguments in function '+obj.constructor.name+'.'+func.name+"\n"+trace;
      throw err;
    }
    if(arguments.length>types.length){
      err.message = 'too many arguments in function '+obj.constructor.name+'.'+func.name+"\n"+trace;
      throw err;
    }
    for(var i=0; i<arguments.length; i++){
      if((arguments[i]===null && types[i]!=="null") 
      || (typeof(arguments[i])==='undefined' && types[i]!=='undefined') 
      || !arguments[i].instanceOf(types[i])
      ){
        err.message = 'argument '+(i+1)+' in function '+obj.constructor.name+'.'+func.name+' must be a '+types[i]+' but '+
                      arguments[i].constructor.name+" is given\n"+trace;
        throw err;
      }
    }
    return func.apply(obj, arguments);
  }
}

Object.prototype.__ = function(types, func){
  var obj = this;
  var f = this[func.name];
  this[func.name] = function(){
    var fail = false;
    var err = TypeError();
    err.validateArgumentsError = true;
    var trace = err.stack.split("\n").slice(3).join("\n");
    try{
      try{
        var argsType = [];
        for (var i=0; i<arguments.length; i++){
          argsType.push(arguments[i]!==null && typeof(arguments[i])!=='undefined' 
                      ? arguments[i].constructor.name 
                      : (arguments[i]===null ? 'null' : 'undefined')
          );
        }
        if(arguments.length<types.length){
          err.message = "there are no method "+obj.constructor.name+'.'+func.name+"("+argsType.join(", ")+")\n"+trace;
          throw err;
        }
        if(arguments.length>types.length){
          err.message = "there are no method "+obj.constructor.name+'.'+func.name+"("+argsType.join(", ")+")\n"+trace;
          throw err;
        }
        for(var i=0; i<arguments.length; i++){
          if((arguments[i]===null && types[i]!=="null") 
          || (typeof(arguments[i])==='undefined' && types[i]!=='undefined') 
          || !arguments[i].instanceOf(types[i])
          ){
            err.message = "there are no method "+obj.constructor.name+'.'+func.name+"("+argsType.join(", ")+")\n"+trace;
            throw err;
          }
        }
      }catch(error){
        fail = true;
        if(typeof(f)!=='undefined'){
          return f.apply(obj, arguments);
        }else{
          throw error;
        }
      }
      if (!fail) {return func.apply(obj, arguments);}
    }catch(higherLevelError){
      if(higherLevelError.validateArgumentsError){
        throw err;
      }else{
        throw higherLevelError;
      }
    }
  }
}

function TObject(){
  this._prototypes=[];
}




Всем заранее спасибо.
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38521165
Dmitry Eliseev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще один велосипед?
Чтобы критиковать, нужно знать исходные цели, которых стремились достичь.
Как уже отмечали, для более "удобной" работы с "объектами можно использовать фреймворки. Например, ExtJS или YUI.
Преимущества фреймворков в поддержке кода, своевременном исправлении ошибок, развитии функционала.
А по существу, для домашней странички нормально, а для среднего/крупного проекта лучше взять фреймворков.
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38521617
Програмёр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry EliseevЕще один велосипед?
Чтобы критиковать, нужно знать исходные цели, которых стремились достичь.
Как уже отмечали, для более "удобной" работы с "объектами можно использовать фреймворки. Например, ExtJS или YUI.
Преимущества фреймворков в поддержке кода, своевременном исправлении ошибок, развитии функционала.
А по существу, для домашней странички нормально, а для среднего/крупного проекта лучше взять фреймворков.

По-моему мы про разное ). Используя ExtJS или YUI можно написать полноценную логику, приложение со сложной структурой? Насколько я понимаю из их описания и из примеров кодов, эти фреймворки, как и jQuery и другие на js, заточены под удобное управление элементами страницы. То есть они все заточены на работу с DOM и расширяют в основном только этот функционал.

Я же пытаюсь расширить функционал js на базовом уровне, а не на уровне работы с DOM.
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38521708
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПрограмёрИспользуя ExtJS или YUI можно написать полноценную логику, приложение со сложной структурой? Насколько я понимаю из их описания и из примеров кодов, эти фреймворки, как и jQuery и другие на js, заточены под удобное управление элементами страницы. То есть они все заточены на работу с DOM и расширяют в основном только этот функционал.Вообще-то 95% js-кода (я исключаю wsh и новомодный серверный js типа node) в конечном итоге с dom и работает. Результат работы js нужно как-то отобразить, чтобы гуманоид за монитором мог его обозреть, и это "как-то" и есть браузер с dom. Сферическое программирование в вакууме, а особенно на js, мало кому интересно.

Что касается ExtJS, то на нем можно написать приложение со сложной структурой, не опускаясь до уровня dom. All inclusive. Да что я мелочусь, даже вообще dom не используя, чисто в сферических целях. Вот где было бы раздолье для ООП, если бы в ExtJS не было более удобного механизма:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Ext.define('MyAnimal', {legs:2, color:'gray', walk:function(){}}); //дефиниция класса со значениями по умолчанию

var a1 = Ext.create('MyAnimal'); //создание экземпляра 
alert(a1.legs);

var a2 = Ext.create('MyAnimal', {legs:4}); //передача параметров в конструктор
alert(a2.legs);

Ext.define('MyBird', {extend:'MyAnimal', wings:2}); //наследование
var b1 = Ext.create('MyBird');
alert(b1.legs);
alert(b1.wings);

Само собой, объекты, помимо определенных разработчиком полей, будут содержать служебные.
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38521819
Dmitry Eliseev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В YUI будет чуть богаче функционал
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
YUI().use('base', function (Y) {
    var MyAnimal = Y.Base.create(/** идентификатор класса */ 'myAnimal', /** базовый класс */ Y.Base, [/** интерфейсы */], {
        /** виртуальные методы */
        walk: function () {}
    }, {
        /** статические методы */
        ATTRS: {
            /** свойства */
            legs: {
                value: 2, /** значение по умолчанию */
                validator: function (val) { /** валидатор свойства */
                    return Y.Lang.isNumber(val) && val >= 0;
                },
                readonly: true /** запрещаем менять свойство после создания объекта */
            }
        }
    });

    var a1 = new MyAnimal(); /** Создаём экземпляр класса */
    alert(a1.get('legs')); /** получение свойства */

    var a2 = new MyAnimal({ legs: 4 }); /** передача свойства в конструктор */
    alert(a2.get('legs'));

    var MyBird = Y.Base.create('myBird', MyAnimal, [], {}, { ATTRS: { wings: { value: 2 } } }); /** Наследуемся */
    var a3 = new MyBird();
    alert(a3.get('legs'));
    alert(a3.get('wings'));
});
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38521947
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry EliseevВ YUI будет чуть богаче функционалОн ориентирован на разработку в многочисленной команде от пары десятков человек, где разные группы людей отвечают за разные участки кода, и одна должна стучать по пальцам другой, если та внезапно делает что-то не то. Иначе я не вижу смысла в статических и виртуальных методах и подобной писанине:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
/** свойства */
            legs: {
                value: 2, /** значение по умолчанию */
                validator: function (val) { /** валидатор свойства */
                    return Y.Lang.isNumber(val) && val >= 0;
                },
                readonly: true /** запрещаем менять свойство после создания объекта */
            }

Если при этом нельзя сделать краткую запись legs:2, то это вообще ахтунг.

Да и реализация этого богатого функционала отнюдь не впечатляет, jquery какое-то:
Код: javascript
1.
a1.get('legs')

Ну фу же по сравнению с a1.legs.

Код: javascript
1.
var a1 = new MyAnimal();

Единственный выигрыш в удобстве, если сравнивать с Ext.сreate.
...
Рейтинг: 0 / 0
покритикуйте пожалуйста
    #38522043
Dmitry Eliseev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
можно не описывать свойства, а просто передать в конструктор { legs:2 } и будет создано такое свойство.
Выражение
Код: sql
1.
 a1.get('legs');


используется потому, что чаще всего требуется чтобы свойство было определённого типа (или принимало определённые значения), поэтому у свойства можно задать начальное значение, геттер/сеттер, валидатор, указать что свойство 'readonly' или 'writeOnce'
Впрочем, можно написать и так:
Код: sql
1.
2.
3.
var MyAnimal = Y.Base.create('my-animal', Y.Base, [], { legs: null, walk: function() {} });
var a1 = new MyAnimal();
alert(a1.legs); 


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

Кстати ещё одна интересная вещь - интерфейсы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
var Positionable = Y.Base.create('positionable', Y.Base, [], {
getX: function () {
    return this.get('x');
},
getY: function () {
    return this.get('y');
},
move: function (x, y) {
    this.set('x', x);
    this.set('y', y);
}
}, {
NAME: 'positionable',
NS: 'positionable'
ATTRS: { x:0, y:0 }
});

var MyAnimal = Y.Base.create('my-animal', Y.Base, [Positionable], {
    walk: function () {
        this.move(this.getX() + 1, this.getY() + 1);
    }
});
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / покритикуйте пожалуйста
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]