Блог Сергея Байдачного

Мой блог о технологиях

Зарисовки по JavaScript для .NET разработчиков: определение типа, undefined и неявное приведение

leave a comment »

Из предыдущих статей Вы уже убедились, что для работы с переменными в JavaScript вовсе необязательно знать тип переменной. Достаточно объявить саму переменную с помощью ключевого слова var, а затем присвоить ей любой объект (включая функцию). Причем повторное присваивание можно выполнить в любом месте кода (естественно в области видимости), присвоив совершенно другой объект. Однако, часто возникает необходимость узнать тип переменной (объекта, на который ссылается переменная).

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

 

   1:  var n = 3;
   2:  var s = "Hello"
   3:   
   4:  //вернет number
   5:  alert(typeof n);
   6:   
   7:  //вернет string
   8:  alert(typeof s);

 

Но, если вы попробуете проделать аналогичное действие с Вашим объектом (функцией), то получите странный результат:

 

   1:  function Person() {
   2:     this.firstName = "Sergey";
   3:     this.lastName = "Baydachnyy";
   4:  };
   5:   
   6:  var obj = new Person();
   7:   
   8:  //вернет object
   9:  alert(typeof obj);

 

Сказать, что механизм отработал неправильно – нельзя (таки object), но нам от этого как-то не очень хорошо.

Поэтому, чтобы определить точный тип объекта, используется специальное свойство – constructor. Это свойство, в отличие от prototype, доступно через ссылку на наш объект, и содержит ссылку на объект-конструктор. Таким образом, можно использовать код ниже:

 

   1:  //возвращает true
   2:  alert(obj.constructor==Person);

 

Вместо constructor можно использовать оператор instanceof, который позволит определить, является ли объект экземпляром заданного типа, но это работает лишь тогда, когда у Вас нет сложной иерархии наследования. Так код ниже напечатает два сообщения TRUE, так как наш объект является как объектом типа Person так и объектом типа Object:

 

   1:  function Person() {
   2:     this.firstName = "Sergey";
   3:     this.lastName = "Baydachnyy";
   4:     this.Name = (function () { return this.firstName + " " + this.lastName; });
   5:  };
   6:   
   7:  Person.prototype.testF = (function () { return "testF"; });
   8:   
   9:  var obj = new Person();
  10:   
  11:  if (obj instanceof Object) {
  12:     alert("TRUE");
  13:  }
  14:   
  15:  if (obj instanceof Person) {
  16:     alert("TRUE");
  17:  }

 

Кроме типа объекта, очень часто необходимо выделить его свойства и методы. Чтобы перечислить все свойства и методы, доступные в объекте, достаточно использовать индексатор:

 

   1:  function Person() {
   2:     this.firstName = "Sergey";
   3:     this.lastName = "Baydachnyy";
   4:     this.Name = (function () { return this.firstName + " " + this.lastName; });
   5:  };
   6:   
   7:  Person.prototype.testF = (function () { return "testF"; });
   8:   
   9:  var obj = new Person();
  10:   
  11:  for (var i in obj) {
  12:     alert(obj[i]);
  13:  }

 

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

 

   1:  function Person() {
   2:     this.firstName = "Sergey";
   3:     this.lastName = "Baydachnyy";
   4:     this.Name = (function () { return this.firstName + " " + this.lastName; });
   5:  };
   6:   
   7:  Person.prototype.testF = (function () { return "testF"; });
   8:   
   9:  var obj = new Person();
  10:   
  11:  for (var i in obj) {
  12:     if (obj.hasOwnProperty(i)&&(typeof obj[i]=="function")) {
  13:        alert(obj[i]);
  14:     }
  15:  }

 

В коде выше мы не только выдаем только методы нашего объекта, исключив свойства и методы прототипа.

Поговорив о типе объектов, хотелось бы остановиться на вопросах преобразования типов. Дело в том, что JavaScript пытается выполнить неявное приведение типов везде, где это возможно. В том же C# конструкция типа int i=0; if (i) {…} являлась бы ошибочной, так как переменная типа int не может быть преобразована к типу bool. В JavaScript же реализовано множество неявных преобразований. Поэтому, чтобы избежать возможной неоднозначности, тут используют сразу два оператора сравнений, это == и === (аналогично != и !==). Первый оператор позволяет выполнить неявное преобразование, а второй – нет. Поэтому, всем разработчикам на .NET рекомендую использовать === и !==, чтобы не получить ошибки, которые в .NET были бы невозможны.

Напоследок отмечу, что если вы пытаетесь получить доступ к свойству или методу, которые не определены (или были удалены) в объекте, то получаете специальное значение undefined. Поэтому, если Вы хотите узнать, существует ли метод или свойство внутри объекта, используйте сравнение с этим значением:

 

   1:  if (obj.val === undefined) {
   2:     alert("Undefined");
   3:  }
Реклама

Written by Sergiy Baydachnyy

29.08.2011 в 07:24

Опубликовано в JavaScript

Tagged with

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: