Web-инжиниринг

Object


Объекты

Объект - это ключевой, главный тип данных JavaScript. Любой другой тип данных имеет объектовую "обертку" - wrapper. Это означает, что прежде чем получить доступ к значению переменной того или иного типа происходит конвертирование переменной в объект, а только после этого выполняются действия над значением. Тип данных Object сам определяет объекты.

В данном разделе мы остановимся на трех основных моментах:

  • понятие объекта
  • прототип объекта
  • методы объекта Object
  • Мы не будем очень подробно вникать во все эти моменты, т.к. при программировании на стороне браузера чаще всего обходятся встроенными средствами JavaScript, но т.к. все эти средства - объекты, нам нужно понимать, с чем имеем дело.

    Понятие объекта

    Для определенности сначала рассмотрим пример произвольного, определенного пользователем объекта, потом определимся с тем, что же это такое:

    function Rectangle(a,b,c,d)

    {

    this.x0 = a;

    this.y0 = b;

    this.x1 = c;

    this.y1 = d;



    this.area = new Function("return Math.abs(this.x0-this.x1)*Math.abs(this.y0-this.y1)");

    this.perimeter = new Function("return (Math.abs(this.x0-this.x1)+Math.abs(this.y0-this.y1))*2");

    }

    c = new Rectangle(0,0,100,100);

    document.write(c.area());

    Результат исполнения:

    function Rectangle(a,b,c,d) { this.x0 = a; this.y0 = b; this.x1 = c; this.y1 = d; this.area = new Function("return Math.abs(this.x0-this.x1)*Math.abs(this.y0-this.y1)"); this.perimeter = new Function("return (Math.abs(this.x0-this.x1)+Math.abs(this.y0-this.y1))*2"); } c = new Rectangle(0,0,100,100); document.write(c.area()+"
    ");

    Этот же пример использован нами в разделе "Функции" для иллюстрации применения конструктора функции. Здесь мы рассмотрим этот пример в более общем контексте.

    Функция Rectangle() - это конструктор объекта класса Rectangle, который определяется пользователем. Конструктор позволяет создать реальный объект данного класса. Ведь функция - это не более чем описание некоторых действий. Для того чтобы эти действия были выполнены, необходимо передать управление функции. В нашем примере это делается при помощи оператора new. Он вызывает функцию и тем самым создает реальный объект.


    Создаются четыре переменных: x0,y0,x1,y1 - это свойства объекта Rectangle. К ним можно получить доступ только в контексте объекта данного класса. Например,:

    up_left_x = c.x0;

    up_left_y = c.y0;

    Кроме свойств мы определили внутри конструктора два объекта типа Function(), применив встроенные конструкторы языка JavaScript, - area и perimeter. Это методы объекта данного класса. Вызвать эти функции можно только в контексте объекта класса Rectangle:

    sq = c.area();

    length = c.perimeter();

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

    На практике довольно редко приходится иметь дело с объектами, созданными программистом. Дело в том, что объект создается функцией-конструктором, которая определяется на конкретной странице и, следовательно, все, что создается в рамках данной страницы не может быть унаследовано другими страницами. Нужны очень веские основания, чтобы автор Web-узла занялся разработкой библиотеки классов объектов пользователя. Гораздо проще писать функции для каждой страницы.


    начало страницы


    Прототип

    Обычно мы имеем дело со встроенными объектами JavaScript. Собственно, все, что изложено в других разделах курса - это обращение к свойствам и методам встроенных объектов. В этом смысле интересно свойство объектов, которое носит название prototype. Прототип - это другое название конструктора объекта конкретного класса. Например, если мы захотим добавить метод к объекту класса String:

    String.prototype.out = new Function("a","a.write(this)");

    ...

    "Привет дуралеи".out(document);

    "Привет дуралеи
    ".out(document);

    Для объявления нового метода для объектов класса String мы применили конструктор Function. Есть один небольшой, но существенный нюанс: новыми методами и свойствами будут обладать только те объекты, которые порождаются после изменения прототипа объекта. Все встроенные объекты создаются до того, как JavaScript программа получит управление, что существенно ограничивает применение свойства prototype.



    Тем не менее покажем, как можно добавить метод к встроенному в JavaScript классу объектов. Примером будет служить встроенный поименованный Image. Задача состоит в том, чтобы разобрать URL картинки таким же образом, как и URL объекта класса Link:

    function prot()

    {

    a = this.src.split(':');

    protocol = a[0]+":";

    return protocol;

    }

    function host()

    {

    a = this.src.split(':');

    path = a[1].split('/');

    return path[2];

    }

    function pathname()

    {

    a = this.src.split(':');

    path = a[1].split('/');

    b = new Array();

    for(i=3;i

    c = b.join('/');

    return "/"+c;

    }

    Image.prototype.protocol = prot;

    Image.prototype.host = host;

    Image.prototype.pathname = pathname;

    ...

    document.write("<img name=i1 src='../images/jsi/ziraf1s.gif'><br>");

    document.write(document.i1.src+"<br>");

    document.write(document.i1.protocol()+"<br>");

    document.write(document.i1.host()+"<br>");

    document.write(document.i1.pathname()+"<br>");

    function prot() { a = this.src.split(':'); protocol = a[0]+":"; return protocol; } function host() { a = this.src.split(':'); path = a[1].split('/'); return path[2]; }

    function pathname()

    {

    a = this.src.split(':');

    path = a[1].split('/');

    b = new Array();

    for(i=3;i");

    Image.prototype.protocol = prot;

    Image.prototype.host = host;

    Image.prototype.pathname = pathname;

    document.write("
    ");

    document.write("

    ");

    document.write("
      ");

      document.write("
    • src: "+document.i1.src+"
      ");

      document.write("
    • протокол: "+document.i1.protocol()+"
      ");

      document.write("
    • хост: "+document.i1.host()+"
      ");

      document.write("
    • путь: "+document.i1.pathname()+"
      ");

      document.write("
    ");

    }

    Основная идея заключается в том, чтобы переопределить конструктор раньше, чем он будет использован. HTML-parser разбирает HTML и создает встроенные объекты раньше, чем запускается JavaScript-интерпретатор. Из этого следует, что объект на странице нужно породить через JavaScript-код. В этом случае сначала происходит переопределение объекта Image, а уже после этого создается встроенный объект этого класса.



    При работе с Explorer все хуже. Если на свойство prototype у строкового объекта он не ругается, то для Image такое свойство уже не определено.


    начало страницы


    Методы объекта Object

    Object - это объект и, следовательно, у него могут быть методы. Таких методов мы рассмотрим три: toString(), valueOf() и assign().

    Метод toString() осуществляет преобразование объекта в строку символов. Он используется в JavaScript программах повсеместно, но неявно. Например, при выводе числа или строковых объектов. Интересно применение toString() к функциям:

    document.write(prot.toString()+"<br>");

    Результат исполнения:

    document.write(prot.toString()+"
    ");

    Здесь мы используем функцию prot() из примера с прототипом. Если распечатать таким же образом объект Image, то получим следующее:

    if(navigator.appName=="Netscape")

    {

    document.write("картинка:"+document.i1.toString()+"
    ");

    }

    else

    {

    document.write("картинка:"+document.images[0].toString()+"
    ");

    }

    Таким образом, далеко не всегда метод toString() возвращает строковый эквивалент содержания объекта. Он может просто вернуть его тип. Ехplorer при этом просто возвращает "Object", в то время как Navigator - "object Image".

    Аналогично ведет себя и метод valueOf(). Этот метод позволяет получить значение объекта. В большинстве случаев работает аналогично методу toString(). Особенно, если нужно значение выводить на страницу:

    document.write(prot.valueOf()+"<br>");

    Результат исполнения:

    document.write(prot.valueOf()+"
    ");

    Как видим результат тот же, что и в методе toString().

    В отличие от двух предыдущих методов метод assign() позволяет не прочитать, а переназначить свойства и методы объекта. Данный метод используется в контексте присваивания объекту некоторого значения:

    object = value; <=> object.assign(value);

    Рассмотрим пример:

    c = new Image();

    c.src = "../images/jsi/rept1s.gif";



    b =new Image();

    b.src = "../images/jsi/rept1g.gif";

    Image.prototype.assign = new Function("a","this.src = a.src;");

    ...

    <a href='javascript:window.document.main.document.i2.assign(c);void(0);'>Покрасить картинку</a>

    c = new Image();

    c.src = "../images/jsi/rept1s.gif";

    b =new Image();

    b.src = "../images/jsi/rept1g.gif";

    if(navigator.appName=="Netscape")

    {

    Image.prototype.assign = new Function("a","this.src = a.src;");

    }



      if(navigator.appName=="Netscape")

      {

      document.write("");

      }

      else

      {

      document.write("");

      }

      Покрасить картинку  

      if(navigator.appName=="Netscape")

      {

      document.write("");

      }

      else

      {

      document.write("");

      }

      Обесцветить картинку  

    В данном примере мы применяем метод assign() не внутри JavaScript-кода, а в обычной HTML-разметке. При этом перед использованием метода мы переопределили его своей функцией.

    Пользователей Explorer следует предупредить, что здесь мы их немножко обманываем, т.к. переназначить прототип Image в Explorer мы в данном случае не можем.


    Содержание раздела