1 (изменено: Orme, 2010-11-22 04:25:42)

Тема: VBScript/JScript Реализация полноценных Setters/Getters в IE

Здравствуйте!

Мне нужно реализовать Setters/Getters в Internet Explorer при чтении/записи определенных свойств объекта JScript. Это возможно сделать, как я понял, исключительно средствами VBScript. В VBScript я - совершенный zero, как это не печально, поэтому прошу помощи.

Значит, производим следующую последовательность действий:

1. На страничке пишем JScript с обработчиками событий, которые будут вызываться при чтении/записи нужных свойств объекта:

<script type="text/jscript">
    function getProp(propName) {
        //Что-нибудь откуда-нибудь возвращаем.
    };
    function setProp(propName, propVal) {
        //Что-нибудь куда-нибудь записываем.
    };
    //Кстати, у меня не получилось потом обратиться к созданному объекту в пределах глобальной области видимости, поэтому, такой танец с бубном:
    function setObjAsTop(obj) {
        window.MyObject = obj;
    };
</script>

2. Далее, пишем VBScript с классом, из которого затем объявим объект, в котором нам, собственно, и нужны будут Setters/Getters.

<script type="text/vbscript">
    Class MyClass
        Public Property Let myProperty(val)
            'Обрабатываем скалярные значения
            setProp "myProperty", val
        End Property
    
        Public Property Set myProperty(val)
            'Обрабатываем объекты
            setProp "myProperty", val
        End Property
        
        Public Property Get myProperty()
            myProperty = getProp "myProperty"
        End Property
    End Class
    
    Dim MyObject
    Set MyObject = New MyClass
    
    'Исполняем танец:
    setObjAsTop MyObject
</script>

3. Ну и проверяем:

<script type="text/jscript">
    MyObject.MyProperty = 42; //Работает!
    MyObject.MyProperty = {foo: 'bar'}; //Работает!
    var foo = MyObject.MyProperty; //Работает!
</script>

Вроде бы, все замечательно, НО! Если нам вдруг понадобится создать ранее не объявленное свойство, напр. MyObject.foo = 'bar', то IE выдаст ошибку Объект не поддерживает это свойство или метод.
Короче, нормально пользоваться этим объектом из JScript нельзя.
Ну, и вопрос: Возможно ли это исправить или обойти?

Спасибо.

2 (изменено: jite, 2010-11-22 07:57:30)

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Orme пишет:

Мне нужно реализовать Setters/Getters в Internet Explorer при чтении/записи определенных свойств объекта JScript. Это возможно сделать, как я понял, исключительно средствами VBScript..

Класс и свойства Get Set в JSc:

function MyObj(x,y) //это класс MyObj
{
  this.GetPlease = function()
  {
    return x + y;
  };
  
  this.SetYo = function(a,b)
  {
    x = a;
    y = b;
  };
}
var oBj = new MyObj(1,2);
//WScript.Echo(oBj.x); //не даст посмотреть

WScript.Echo("GetPlease()=>"+ oBj.GetPlease());
oBj.SetYo(0, 42)
WScript.Echo("GetPlease()=>"+ oBj.GetPlease());

Глубже.

3

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Хорошо, что этот модуль у себя на почте нашел в отправленных письмах:)

<script>
var Watch = 
{    
    createObject : function ()
    {    
        var    node = document.createElement('SPAN');
            node.onpropertychange = Watch.__IE_onchange;

        var    container         = node.style;                
            container._index  = Watch.__watchers.length;
            Watch.__watchers[container._index] = {};
            
            container.watch   = function (propertyName, userFunction) 
            {
                var w = Watch.__watchers;
        
                    w[this._index][propertyName] = userFunction;
                    w[this._index][propertyName].oldValue = this[propertyName];
            }
            
            document.body.appendChild(node);
            return container;
    },

    __watchers : [],

    __IE_onchange : function () 
    {
        var p = event.propertyName.split('.')[1], //property
            c = event.srcElement.style, //container
            f = Watch.__watchers[c._index][p]; //function

            if (f && (f.oldValue!=c[p])) 
                c[p] = f.oldValue = f(p, f.oldValue, c[p]);

    }
};


window.onload= function()
{
    var a=Watch.createObject();
    a.q=0;
    a.watch("q", function(q,w,e) {alert([q,w,e]);});
    a.q=1;
}
</script>

4 (изменено: Orme, 2010-11-23 02:27:57)

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Спасибо, конечно, но немножко не то. Нужно, чтобы выполнялись некие действия при чтении/записи именно свойства, а не при выполнении метода. Т.е. реализация полноценных setters/getters как на javascript:

<script type="text/javascript">
    var obj = {
        get x() {
            //code...
        },
        set x(v) {
            //code...
        }
    };
    //или:
    var obj = {};
    obj.__defineGetter__('x', function() { /*code*/ });
    obj.__defineSetter__('x', function(v) { /*code*/ });
</script>

И при чтении/записи свойства x объекта obj будет выполняться code. Это все не работает в JScript/IE, и единственный способ это реализовать - воспользоваться VBScript, как описано мной выше. Но созданный в VBScript объект не позволяет добавлять к себе новые свойства/методы из JScript. Фиксить это надо на VBScript, если это воообще возможно.
Нигде не нашел решения, к сожалению. Может кто-нибудь знает?

5 (изменено: JSmаn, 2010-11-23 08:32:22)

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Механим watch при внесении некоторых изменений вполне годится для эмуляции сеттера. Хотя вариант использования VBS мне больше нравится.

6

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Да, на VBS помоему было бы фундаметнальнее, если бы кто-нибудь рассказал, как на VBS создать объект из класса, чтобы затем в этот объект можно было свободно записывать свойства/методы, не объявленные ранее в классе.
Комрады, кто-нибудь знает, это вообще возможно?

7 (изменено: jite, 2010-11-24 00:49:46)

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

По поводу возможности создания getters-setters (далее G&S) в JScript из обсуждения на StackOverflow ровно (!) год назад.

Вольный перевод высказываний:

1: Ответ - нет. Попытки организовать их эмуляцию в HTML-элементах <=IE7 потерпели неудачу из-за сложности воплощения. Даже IE8 G&S поддерживаются только в DOM объектах и не для JScript объектов... Хорошо б разработчики это воплотили позже.

2: Не думаю, что это хорошая идея, потому что понять синтаксис будет непросто...

3: Просто для информации: в IE8 G&S сделаны только для объектов DOM. На вопросы о причинах ограничения разработчики MS сообщили, что фича из разряда "добавлено в последнюю минуту" и до JScript просто не дошли руки. Так что скрестим пальцы, может в IE9 это сделают полностью.

4: G&S поддерживаются в JScript.NET 8

8

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Orme пишет:

как на VBS создать объект из класса, чтобы затем в этот объект можно было свободно записывать свойства/методы, не объявленные ранее в классе.

Тоже задумывался на этот счет для VBS, привыкнув к простоте добавления в JSc. Но пока не придумал ничего лучше, чем создавать Dictionary и пользоваться его ключами как свойствами, Ну и при необходимости можно засунуть его в класс.

Впрочем в VBS я новичок, может есть способы лучше?

9

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

jite пишет:

По поводу возможности создания getters-setters (далее G&S) в JScript из обсуждения на StackOverflow ровно (!) год назад.

Вольный перевод высказываний:

1: Ответ - нет...

Насчет JScript все понятно, там нельзя... Но ведь в VBS можно через Get/Set/Let в классах? А в IE у JScript и VBS общее пространство имен, поэтому объекты с s&g, созданные в VBS, можно потом юзать из под JS. Я ж говорю, механизм был бы полноценным, если бы затем можно было бы свободно записывать свойства/методы в объект VBS. Вопрос в том, как это реализовать, и вообще, возможно ли? Если да, то вообще, необходимый VBS код можно было бы прям из JS генерировать, и было бы счастье ) Я мануалов на этот счет вообще не нашел, на msdn/vbs вообще reference какой-то убогий - ни примеров, ни коментов...

10

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Думаю, что проще ограничиться технологией wsc. Не вижу особого смысла на лету расширять объекты.

11

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Почему нет смысла? Ну, допустим, мне нужно сделать wrapper для некоего js кода, который будет писать вообще незнакомый мне чел.
Ну например:

var MyObject = {
    myPropertyObjectWithGS: {}
}
MyObject.myPropertyObjectWithGS.__defineGetter__('x', function() { /*обрабатываем*/ });
MyObject.myPropertyObjectWithGS.__defineSetter__('x', function(val) { /*обрабатываем*/ })
with (MyObject ) {
    //посторонний код (мне неизвестный), в котором кодер делает вот так:
    myPropertyObjectWithGS.x = 'y'; //вот это мне просто позарез надо обработать
    var foo = myPropertyObjectWithGS.x; //и такое тоже надо полюбому вообще

    //но ведь кодер имеет полное право сделать и вот так:
    myPropertyObjectWithGS.foo = 'bar';
    //или так:
    myPropertyObjectWithGS.foo = {bar: 42};
    //или даже так:
    myPropertyObjectWithGS.foo = function() { /*...*/ };
    
    //и пусть себе делает, это ж в рамках языка, но вот IE не даст.
}

Товарищи, кто-нибудь может с уверенностью сказать, что в VBS нельзя на лету расширять объекты? Может там какое-нить default property или еще что-нибудь...

12

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

конечно дико извиняюся, но как бы может ничего не понимаю

<html>
<script type="text/javascript">
var MyObject = {
    myPropertyObjectWithGS: {}
}
Object.prototype.GetGetter=function() {
    for (i in this) {
        if (i != "GetGetter")
            alert(i+"="+eval("this."+i));
            }
        };
MyObject.myPropertyObjectWithGS.y=1;
MyObject.myPropertyObjectWithGS.x=2;
MyObject.y='y';
MyObject.x='x';


</script>
<body onload="MyObject.myPropertyObjectWithGS.GetGetter();MyObject.GetGetter();">
</body>
</html>
Я конечно далек от мысли... (с)

13

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

1. VBS не может расширить экземпляр класса. Это я говорю с уверенностью.
2. Orme, код который вы привели предназначен для Мозиллы. У нее своя реализация JavaScript.
3. В рамках JS с компонентом WebBrowser можно делать только сеттеры.

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

14

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

как бы вкурсе, но так ли надо при программном изменении отслеживать событие ?

Я конечно далек от мысли... (с)

15 (изменено: Orme, 2010-12-01 03:31:08)

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

JSman, то что в VBS нельзя расширять экземпляр класса - это печально, по крайней мере для меня. MS в очередной раз "порадовали". Кстати, g&s замечательно работают на всех движках, кроме trident'а. Не в курсе, когда MS собираются ввести g&s? В IE9 beta не работают, неужели так руки и не дошли?

16

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

Orme, в настоящий момент я вижу развитие языка в положительную сторону в связи с появлением  нового движка JScript (Chakra), который будет работать с ActiveX. С другой стороны новая версия не совместима со старыми стандартными интерпретаторами JS, да и вряд ли будет доступна на XP. Поэтому если уж точно выбрали использовать среду WSH, то нужно отвыкнуть от преимуществ движков "конкурентов" (в частности watch, геттеры и сеттеры) или создавать свои ActiveX.

smaharbA пишет:

как бы вкурсе, но так ли надо при программном изменении отслеживать событие ?

Я, например, сторонник использовать методы и свойства объекта (синтаксически), чем одни методы. В больших объемах кода не раз сталкивался с проблемой отслеживания за изменением переменной.

17

Re: VBScript/JScript Реализация полноценных Setters/Getters в IE

А может быть можно как-то профиксить объект VBS уже из JSc? Вообще, как VBS объект классифицируется в JSc? Какой там constructor? Может надо покапаться в COM? Кто-нибудь в этом шарит, извиняюсь, разбирается?