博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js类型判断及鸭式辨型
阅读量:5081 次
发布时间:2019-06-12

本文共 3824 字,大约阅读时间需要 12 分钟。

 目录

 

 

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

用法如下:

1)instanceof

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

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

 

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

var a1 = new Array();console.log(Array.prototype.isPrototypeOf(a1));trueconsole.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,3String:abcNumber: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()); //输出truePerson {}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()); //输出falseObject {toString: function}function Function() { [native code] }jsjs

此时新定义的原型对象不含有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

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

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

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

 

在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

 

 

 

 

转载于:https://www.cnblogs.com/wishyouhappy/p/3721778.html

你可能感兴趣的文章
题解:luoguP1861 星之器
查看>>
自定义日志类
查看>>
栗染-git命令搭建简单的个人的网页
查看>>
jvm 这我就能会了 擦
查看>>
实战技能:小小微信支付业务,何必虚惊一场
查看>>
EasyUI DataGrid结合ThinkPHP实现增删改查操作———初学者
查看>>
17-1 djanjo进阶-路由,视图,模板
查看>>
06-图1 列出连通集
查看>>
另类游戏开发人员的趣闻轶事
查看>>
JavaScript正则表达式检验手机号码、邮箱、ip地址等
查看>>
js中对象概念的声明
查看>>
Shell脚本8种字符串截取方法总结
查看>>
P3254 圆桌问题
查看>>
MapReduce的运行原理
查看>>
Leetcode: Partition List
查看>>
故障转移
查看>>
清空dataset中的某行某列的数据
查看>>
盒模型
查看>>
Python argparse 子命令
查看>>
安装了简易版XP系统后不能安装IIS的解决办法
查看>>