深刻探究JavaScript对象系列(六)

一.类和类型

  在传统的面向对象的编程语言中,有很好的方法可以判断一个实例对象属于哪一个类,可是在js中,并无完美方法来实现这个功能,可是仍是有几种方法来弥补,下面介绍3种:程序员

  a.instanceof运算符和isPrototype()方法,编程

  instanceof操做符的左操做数是待检测其类的对象,右操做数是定义类的构造函数,若是o继承自c.prototype,则表达式 o instanceof c 返回true.,此外当o继承自一个也继承自c.prototype的对象时也会返回true;一样的isPrototype()方法也能实现相似功能,即在多个执行上下文场景中没法正常工做。数组

  可是着两个都没法经过对象来得到类名,此外在客户端JavaScript中,出现多窗口和多框架子页面中兼容性不佳框架

  b.constructor属性编程语言

  这个属性在上一篇中刚刚提到过,用这个属性能够得到类名,但在多个执行上下文中的场景中也没法政策工做,并且并非全部的对象中都具备这个属性。函数

  c。使用构造函数的函数名spa

  上述的两类方法在用来检测对象所属类中都有“多个执行上下文场景中没法正常工做”的问题,一种可能的解决方案是使用构造函数名称字符串,可是这样作在当构造函数没有名称的时候也没法正常工做。prototype

二.鸭式辩型

  鸭式辩型这个思考问题的方式是由James Riley提出的,它的思想是:像鸭子同样走路,游泳而且嘎嘎叫的鸟就是鸭子。code

  对于程序员来讲:不要关注对象类型是什么,而是关注对象能作什么。拿上一篇中的例二来讲,Range中的includes方法并无对实参进行类型检测以确保它是数字类型,就直接拿来比较;此外在类数组对象中这点显得尤其明显,在不少场景虾,咱们并不知道一个对象是否为数组对象,能够经过判断该对象是否包含一个length的属性,有就认为它是数组对象,即这只“鸭子”会游泳了,会不会走路和嘎嘎叫则不去判断。对象

  鸭式辩型的实现方法让人感受太“听任自流”:仅仅是假设输入的对象实现了必要的方法,没有进一步执行检查。若是输入对象没有遵循以前的“假设”,那么当代码试图调用那些根本不存在的方法时就会报错;另外一种实现方法是对输入对象进行检查,但不是检查它们的类,而是用适合的名字来检查它们所实现的方法,这样能够将非法输入尽量的拦截在前,并给出有效提示,请看下面的例子:

 1 function quacks(o /*,...*/){
 2     for (var i = 1; i < arguments.length; i++) {
 3         var arg = arguments[i];
 4         switch(typeof arg){
 5             case "string" :       //直接用名字作检查
 6                 if(typeof o[arg] !== "function") return false;
 7                 continue;
 8             case "function" :
 9                 arg = arg.prototype;
10                 continue;
11             case "object":
12                 for(var m in arg){
13                     if(typeof arg[m] !== "function") continue;
14                     if(typeof o[m] !== "function") return false;
15                 }
16                 continue;
17         }
18     }
19     return true;
20 }

  关于这个quacks函数有亮点须要注意:咱们只是经过给定的名称来检测对象是否知足要求,但没法得知其细节,而这也正是鸭式辩型的本质所在;此外该函数该函数不能应用于内置类,由于内置类中的方法都是没法经过for/in来遍历的。

  到此为止,算上以前5篇,再加上这一篇基本上以及把JavaScript中的面向对象的基础介绍完了,接下来会介绍些JavaScript中关于面向对象编程的技术,固然仍是基于David Flanagan大神的那本《JavaScript权威指南》。

相关文章
相关标签/搜索