在传统的面向对象的编程语言中,有很好的方法可以判断一个实例对象属于哪一个类,可是在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权威指南》。