目录

instanceof

constructor

构造函数名字

鸭式辨型

三种检测对象的类方式: instanceof、constructor 、构造函数名字

用法如下:

1)instanceof

console.log([1,2,3] instanceof Array);
true console.log([1,2,3] instanceof Object);
true

尽管构造函数是原型的唯一标识,instanceof运算符的右操作数是构造函数,instanceof实际计算过程中检测的是对象的继承关系,而不是检测的创建对象时的构造函数,只是使用了构造函数作为中介

当然也可以使用isPrototypeOf 来判断一个对象是否存在于另一对象的原型链中,此时不使用构造函数作为中介

var a1 = new Array();
console.log(Array.prototype.isPrototypeOf(a1));
true console.log(Array.prototype.isPrototypeOf([1,2,3]));
true

注意:多个执行上下文时(例如存在不同框架时)instanceof使用有限制

2)constructor

每个javascript函数都可以用作构造函数,调用构造函数需要使用prototype属性,因而每个javascript函数会自动拥有prototype属性,这个属性值是一个对象,这个对象包含一个contructor属性,constructor属性值是一个函数对象。

即对于函数var F = function(){}; F.prototype.constructor===F

关系图如下:

eg:

var F= function(){};
var p = F.prototype;
var c = p.constructor;
console.log(p);
console.log(c);
console.log(c===F);
Object {}
function (){}
true

因而对象继承的constructor均指代他们的构造函数

eg:

var o= new F();
console.log(o.constructor===F);
//输出 
true
var a = new Array();
console.log(a.constructor===Array);
//输出
true
function typeDiscern(x){
switch(x.constructor){
case Number: return "Number:"+x;
case String: return "String:"+x;
case Array: return "Array:"+x;
}
}
console.log(typeDiscern([1,2,3]));
console.log(typeDiscern("abc"));
console.log(typeDiscern(5));
//输出
Array:1,2,3
String:abc
Number:5

注意: 同instanceof在多个上下文下没法使用,另外并不是所有的对象都包含constructor属性

eg:

定义Person类

function Person(name)
{
this.name=name;
this.getName=function()
{
return this.name;
}
}; var wish=new Person('js'); console.log(wish.constructor==Person);
console.log(Person.prototype);
console.log(Person.constructor);
console.log(wish.getName()); //输出
true
Person {}
function Function() { [native code] }
js

给Person自定义prototype

function Person(name)
{
this.name=name;
this.getName=function()
{
return this.name;
}
};
Person.prototype={
toString: function(){
return this.name;
}
}; var wish=new Person('js'); console.log(wish.constructor==Person);
console.log(Person.prototype);
console.log(Person.constructor);
console.log(wish.getName());
console.log(wish.toString()); //输出
false
Object {toString: function}
function Function() { [native code] }
js
js

此时新定义的原型对象不含有constructor属性,因而Person的实例也不包含constructor属性

解决方法:可显示的给原型添加构造方法

Person.prototype={
constructor=Person,
toString: function(){
return this.name;
}
};

构造函数名字

没有intanceof和constructor的执行上下文问题,一个窗口中的Array构造函数和另一个窗口内Array构造函数不等,但是构造函数名字相同,但是并不是每个函数都有名字

Function.prototype.getName= function(){
if("name" in this){
return this.name;
}
return this.name=this.toString().match(/function\s*([^(]*)/);
}
function test1(){
}
console.log(test1.getName()); //输出:
test1

鸭式辨型

关注对象能做什么,而不是对象的类是什么

James Whitcomb Riley提出像鸭子一样走路、游泳和嘎嘎叫的鸟就是鸭子

主要对象包含walk(),swim(),bike()这三个方法就可以作为参数传入

利用鸭式辩型实现的函数:

function quackImplements(o/*,...*/){
for(var i=1; i<arguments.length;i++){
var arg=arguments[i];
switch(typeof arg){
case 'string':
if(typeof o[arg]!=="function")
return false;
continue; case 'function':
arg=arg.prototype; case 'object':
for (var m in arg){
if(typeof arg[m]!=="function") continue;
if(typeof o[m]!=="function") return false; }
}
}
return true;
}

对于字符串直接检查命名方法

对于对象检查是否有同名方法

对于函数检查构造函数的原型对象中是否有相同方法

在javascript中很多函数都不对对象做类型检测只是关心这些对象能做什么

eg:Array的prototype利用了鸭式辨型,arguments是伪数组

 (function () {
var arr = Array.prototype.slice.apply(arguments);
console.log(arr);
})(1, 2, 3); //输出:
[1, 2, 3]
 var arr = Array.prototype.slice.apply({ 0: 1, 1: 2, 2: 3, length: 3 });
console.log(arr); //输出:
[1, 2, 3]

使用鸭式辨型可以扩大对象的使用范围

eg:让普通对象具有数组的push方法

Function.prototype.unCurrying = function () {
var f = this;
return function () {
var a = arguments;
return f.apply(a[0], [].slice.call(a, 1));
};
};
Function.prototype.unCurrying = function () {
return this.call.bind(this);
}; var push = Array.prototype.push.unCurrying(),
obj = {};
push(obj, 'first', 'two');
console.log(obj);
console.log("length:"+obj.length)

输出:

Object{0: "first", 1: "two", length: 2}
length:2

参考:javascript权威指南

    http://www.cnblogs.com/pigtail/p/3450852.html

js类型判断及鸭式辨型的更多相关文章

  1. js 鸭式辨型法

    无意中看到arr.length === +arr.length;这句代码,然后就去了解了下 这是一种鸭式辨型的判断方法. 鸭式辨型:像鸭子一样走路.游泳和嘎嘎叫的鸟就是鸭子 这句话表示: a.arr有 ...

  2. 类型和原生函数及类型转换(二:终结js类型判断)

    typeof instanceof isArray() Object.prototype.toString.call() DOM对象与DOM集合对象的类型判断 一.typeof typeof是一个一元 ...

  3. JS类型判断&原型链

    JS类型检测主要有四种 1.typeof Obj 2.L instanceof R 3.Object.prototype.toString.call/apply(); 4.Obj.constructo ...

  4. js类型判断-丰富加好用

    一, 自己有时候写一些东西,要做类型判断,还有测试的时候,对于原生的和jQuery中的类型判断,实在不敢恭维,所以就写了一个好用的类型判断,一般情况都够用的. function test(type) ...

  5. 看jquery3.3.1学js类型判断的技巧

    需要预习:call , typeof, js数据类型 1. isFunction中typeof的不靠谱 源码: var isFunction = function isFunction( obj ) ...

  6. JS类型判断typeof PK {}.toString.call(obj)

    参考链接:https://www.talkingcoder.com/article/6333557442705696719 先看typeof <!doctype html> <htm ...

  7. js类型判断:typeof与instanceof

    typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: number,boolean,string,function(函数),object(NULL,数组,对象),und ...

  8. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  9. js类型判断

    console.log('---------------------'); var a="string"; console.log(a); //string var a=1; co ...

随机推荐

  1. Jquery中的事件绑定$(&quot;#btn&quot;).bind(&quot;click&quot;,function(){ })

    Jquery中的事件绑定:$("#btn").bind("click",function(){  }) 由于每次都这么调用太麻烦,所以jquery就用$(&qu ...

  2. C/C++笔试题整理

    1. C的结构体和C++结构体的区别 (1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数.所以C的结构体是没有构造函数.析构函数.和this指针的. (2)C的结构体对 ...

  3. Linux下/etc/fstab文件详解

    当系统启动的时候,系统会自动地从这个文件读取信息,并且会自动将此文件中指定的文件系统挂载到指定的目录. [root@rusky ~]# vi /etc/fstab # # /etc/fstab # C ...

  4. HDU -2298 Toxophily(三分法)

    这道题目,可以推出物理公式直接来做,但是如果推不出来就必须用程序的一种算法来实现了,物理公式只是适合这一个或者某个题,但是这种下面这种解决问题的方法确实解决了一类问题 ----三分法,大家可能都听说过 ...

  5. python环境准备

    一.环境准备. 1.安装python3.5.2(勾选环境变量),python2.7.12 2.设置环境变量 (要求命令行输入python,进入python2命令行,打python3时,进入python ...

  6. Word 查找替换,通配符一览表

    Word查找替换详细用法及通配符一览表 使用通配符要查找“?”或者“*”,可输入“\?”和“\*”,\1\2\3依次匹配数对括号内容查找(a)12(b)   替换\2XY\1   结果:bXYa ([ ...

  7. Dhroid框架笔记(IOC、EventBus)

    dhroid 目前包含了6大组件供大家使用1.Ioc容器: (用过spring的都知道)视图注入,对象注入,接口注入,解决类依赖关系2.Eventbus: android平台事件总线框架,独创延时事件 ...

  8. iOSUI基础——懒加载

    1.懒加载基本 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化 ...

  9. UIView之常用属性

    UIView之常用属性 1. view.tag = 200; // 系统保留0-1002. view.frame = CGRectMake(20, 30, 300, 300);3. view.cent ...

  10. css水平居中的小小探讨

    水平居中是常用的几种布局方式之一.主要分为行内元素的居中,块元素的居中.块元素的居中还分为固定宽度的居中,不定宽度的居中.行内元素的居中,使用text-align:center就可以实现,已知宽度的块 ...