Page 185 - Браун Э. - Изучаем JavaScript. Руководство по созданию современных веб-сайтов - 2017
P. 185

его собственного класса, но и любых суперклассов. На многих объектно-ориентиро­
       ванных языках полиморфизм - это нечто особенное, приносящее большую пользу
       ООП. Язык JavaScript не является типизированным, т.е. любой объект может быть
       использован в любом месте (хотя правильный результат не гарантирован). Таким об­
       разом, в некотором смысле у JavaScript есть абсолютный полиморфизм.
          Код  JavaScript,  который  вы пишете,  довольно  часто  использует  некую  форму
       утиной  типизации (duck typing).  Эта методика исходит из выражения "Если это
       выглядит, как утка, плавает, как утка и крякает, как утка, то это, возможно, и есть
       утка': В нашем примере с классом Car, если у вас есть объект, обладающий методом
       deployAirbags, то вы могли бы резонно заключить, что это экземпляр  класса Car.
       Это может быть правда, а может и нет, но попытка довольно хорошая.
          В JavaScript предусмотрен оператор instanceof, который укажет вам, является ли
       объект экземпляром данного класса. Как ни удивительно, но до тех пор, пока вы не
       оперируете напрямую свойствами prototype и  _ proto _, этот оператор будет воз­
       вращать правильный результат.
       class  Motorcycle  extends  Vehicle  { }
                       r
       const  с  =    new  Ca ( ) ;
       const  m  =  new  Motorcyle ( ) ;
       с  instanceof  Car ;        1 1   true
       с  instanceof  Vehicle;     1 1   true
       m  instanceof  Car;         1 1   false
       m  instanceof  Motorcycle ;   1 1   true
       m  instanceof  Vehicle ;    1 1   true
                  Все  объекты  в  JavaScript  являются  экземплярами  корневого  клас­
                       j
                  са  Ob e c t .   Таким  образом,  для  любого  объекта  о  выражение  о
                  instanceof  Ob e ct будет истинным (если только вы явно не устано­
                                j
                  вите значение его свойства _proto _, чего следует избегать). С прак­
                  тической точки зрения в этом есть небольшой смысл, поскольку такая
                  возможность позволяет создать ряд важных методов для всех объек­
                  тов иерархии. В качестве примера можно привести метод toString,
                  который будет рассмотрен ниже в этой главе.


       Перебор свойств объектов (снова}
          Мы уже видели, как можно перебрать свойства объекта в цикле for  . .   in. Т е перь,
                                                                       .
       когда мы понимаем механизм наследования прототипов, мы можем полностью оце­
       нить использование метода hasOwnProperty при переборе свойств объекта. Для объ­
                                                                t
                                                   (
       екта obj и свойства х вызов obj . hasOwnProperty  х )   возвратит  r ue, если у obj будет
                                      х
       свойство х, и false, если свойство  н е определено или определено в цепи прототипов.
          Если  вы будете  использовать  классы  ES6  так,  как  они  задуманы, то свойства
       данных всегда будут определяться в экземплярах, а не в цепи прототипов. Однако,


       1 8 6    Глава 9. Объекты и объектно-ориентированное программирование
   180   181   182   183   184   185   186   187   188   189   190