JavaScript用构造函数如何获取变量的类型名


Posted in Javascript onDecember 23, 2016

使用 typeof 获取基本的类型

看到题目的第一眼,有些同学可能会想到 typeof 运算符,在JavaScript语言中,给出了使用 typeof 运算符来获取基本的类型名.(注意不是基本类型)

这是 typeof 的全部用法

01-typeof.htm

console.log('typeof of 10 ~~~~' +typeof 10);
console.log('typeof of "a" ~~~~' +typeof 'a');
console.log('typeof of true ~~~~' +typeof true);
console.log('typeof of {} ~~~~' +typeof {});
console.log('typeof of /123/ ~~~~' +typeof /123/);
console.log('typeof of function(){} ~~~~' +typeof function(){});
console.log('typeof of undefined ~~~~' +typeof undefined);
console.log('typeof of null ~~~~' +typeof null);

这是结果

JavaScript用构造函数如何获取变量的类型名

按照上面的打印结果,总结出下面要注意的几点

typeof (引用类型) 除了函数, 都是 'object',比如 typeof /123/

typeof null 为'object'

typeof undefined 为 'undefined',通常, 如果使用两等号, null == undefined 为真.

转换为数字的常见用法 "10"-0, 如果没有转换成功,返回NaN,由于NaN 的一个特性: NaN != NaN ,故判断转换成功与否的常见做法: (这也是我参见 jQuery的源码发现的,jQuery源码读100遍都不为过)

("10x" - 0) == ("10x" - 0);
 // 结果为假!

JavaScript用构造函数如何获取变量的类型名

使用jQuery中的方法$.type()

现在看看jQuery是怎么做的

// 先申明一个对象,目的是用来做映射
var class2type = {};
// 申明一个core_toString() 的方法,得到最原始的toString() 方法,因为在很多对象中,toStrintg() 已经被重写 
var core_toString() = class2type.toString;
// 这里为 toStrintg() 后的结果和类型名做一个映射,申明一个core_toString() 后的结果,而值就是类型名
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
 class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

因为 Object.prototype.toString() 方法调用结果如下

var core_toString = {}.toString;
console.log( core_toString.call(1) );
console.log( core_toString.call("11") );
console.log( core_toString.call(/123/) );
console.log( core_toString.call({}) );
console.log( core_toString.call(function(){}) );
console.log( core_toString.call([]) );
console.log( core_toString.call(true) );
console.log( core_toString.call(new Date()) );
console.log( core_toString.call(new Error() ));
console.log( core_toString.call(null) );
console.log( core_toString.call(undefined) );
console.log( String(null) );
console.log( String(undefined) );

JavaScript用构造函数如何获取变量的类型名

上面的打印结果与

class2type[ "[object " + name + "]" ] = name.toLowerCase();

不谋而合!

这是jQuery.type 的核心方法

type: function( obj ) {
 if ( obj == null ) {
 return String( obj );
 }
 // Support: Safari <= 5.1 (functionish RegExp)
 return typeof obj === "object" || typeof obj === "function" ?
 class2type[ core_toString.call(obj) ] || "object" :
 typeof obj;
},

注意,为什么把 null 或者 undefined 单独讨论呢,因为 在一些版本浏览器中

console.log(core_toString.call(null));
console.log(core_toString.call(undefined));

这是会报错的!

如果是对象类型,另:由于 在一些低版本的浏览器中,typeof /123/ 会返回的是 "function" 而不是 "object",所以这里要判断是否是函数,要明白 这里的 typeof obj === function 不是为了函数讨论的,因为函数本身就可以通过typeof 来得到类型.

typeof obj === "object" || typeof obj === "function" ?
 class2type[ core_toString.call(obj) ]

就直接返回class2type 中键值对的结果,,如果不是,那么一定就是基本类型, 通过 typeof 就可以啦.

class2type[ core_toString.call(obj) ] || "object" :
// 这是防止一些未知情况的,如果未取到,就返回object

但是 jQuery.type 有一个很大的缺陷

这是一个自定义类型

function Person(){
 this.name = 'pawn';
}
var p = Person.toString();

// 注意,这里会打印 [object Object],通过上面的方法,无法得到精确的自定义类型

这也是 它的一个大缺陷了!

下面,我们通过构造函数的方式来获取精确类型

通过构造函数来获取类型

这种方式 是蒋坤老师( jk ) 教会我的,非常感谢他.

在理解这个方法之前,需要理解两个点

prorotype 原型属性

我们知道,任何对象或者函数都直接或者间接的继承自Object 或者 Function, (其实最终Function 是继承自 Object 的,这属于原型链的知识了)。那么,任何一个对象都具有原型对象 __proto__ (这个对象只在chrome 和 firefox 暴露,但是在其他浏览器中也是存在的),这个原型对象就是这个对象的构造函数的原型属性(这里可能有点绕).


由于 任何函数都具有 原型属性prototype,并且这个原型属性具有一个默认属性 constructor,它是这个函数的引用,看下面的代码

function Person(){
 this.name = 'pawn';
 }
 console.log(Person.prototype.constructor === Person);

JavaScript用构造函数如何获取变量的类型名

​发现,这两个东西其实一个东西

但是,在某些情况下,需要这么写

function Person(){
 this.name = 'pawn';
 }
 Person.protype = {
 XX: ... ,
 xx: ... ,
 ...
 }

这么做,就会覆盖原本的 protype 方法,那么construcor 就不存在了,这是,必须要显示的申明这个对象

Person.protype = {
 construction: Person,
 XX: ... ,
 xx: ... ,
 ...
 }

在jQuery的中,就是这么做的,

jQuery.fn = jQuery.prototype = {
 constructor: jQuery,
 init: function( selector, context, rootjQuery ) {
 var match, elem;

关于 jQuery对象封装的方式 也是非常值得研究

Function.prototype.toString()

JavaScript用构造函数如何获取变量的类型名

注意,这里已经不是熟悉 [object Object],而是 已经重写了.

也就是,如果调用一个函数的toString() 方法.那么就会打印这个函数的函数体.

JavaScript用构造函数如何获取变量的类型名

好了,经过上面两个步骤,你明白我要做什么了吗?

如何通过构造函数来获得变量的类型?

判断是否是基本类型

var getType = function(obj){
 if(obj == null){
 return String(obj);
 }
 if(typeof obj === 'object' || typeof obj === 'fucntion'){
 ...
 }else{
 // 如果不是引用类型,那么就是基本类型
 return typeof obj
 }
 }

如果是对象或者函数类型

function Person(){
 this.name = 'pawn';
 }
 var p = new Person();
 console.log(p.constructor);

JavaScript用构造函数如何获取变量的类型名

现在要做的事 : 如何将Person 提取出来呢?

毋庸置疑,字符串切割那一套肯定可以办到,但是太 low 啦!

这里,我使用正则将Person提取出来

var regex = /function\s(.+?)\(/
function Person(){
 this.name = 'pawn';
 }
 var p = new Person();
 var c = p.constructor
 var regex = /function\s(.+?)\(/;
 console.log('|' + regex.exec(c)[1] + '|');

JavaScript用构造函数如何获取变量的类型名

使用name

其实,除了上面的正则,每个函数还有一个name属性,返回函数名,但是ie8 是不支持的.

因此上面的代码可以写为:

var getType = function(obj){
 if(obj == null){
 return String(obj);
 }
 if(typeof obj === 'object' || typeof obj === 'function'){ 
 var constructor = obj.constructor;
 if(constructor && constructor.name){
 return constructor.name;
 }
 var regex = /function\s(.+?)\(/;
 return regex.exec(c)[1];
 }else{
 // 如果不是引用类型,那么就是基本;类型
 return typeof obj;
 }
};

但是上面的代码太丑啦,将其简化

简化

var getType = function(obj){
 if(obj == null){
 return String(obj);
 }
 if(typeof obj === 'object' || typeof obj === 'function'){ 
 return obj.constructor && obj.constructor.name.toLowerCase() || 
 /function\s(.+?)\(/.exec(obj.constructor)[1].toLowerCase();
 }else{
 // 如果不是引用类型,那么就是基本类型
 return typeof obj;
 }
};

还是比较麻烦,继续简化

var getType = function(obj){
 if(obj == null){
 return String(obj);
 }
 return typeof obj === 'object' || typeof obj === 'function' ?
 obj.constructor && obj.constructor.name && obj.constructor.name.toLowerCase() ||
 /function\s(.+?)\(/.exec(obj.constructor)[1].toLowerCase():
 typeof obj;
};

好了,已经全部弄完了,写个代码测试一下:

function Person(){
 this.name = 'pawn';
}
var p = new Person();

console.log(getType(p));
console.log(getType(1));
console.log(getType("a"));
console.log(getType(false));
console.log(getType(/123/));
console.log(getType({}));
console.log(getType(function(){}));
console.log(getType(new Date()));
console.log(getType(new Error()));
console.log(getType( null));
console.log(getType( undefined));

JavaScript用构造函数如何获取变量的类型名

总结

好了,以上就是关于如何获取变量的类型名的全部介绍了,希望本文的内容能对你提供帮助。如果有疑问大家可以留言交流。

Javascript 相关文章推荐
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
Aug 13 Javascript
超强的IE背景图片闪烁(抖动)的解决办法
Sep 09 Javascript
jQuery 中使用JSON的实现代码
Dec 01 Javascript
iframe里的页面禁止右键事件的方法
Jun 10 Javascript
ECMAScript5中的对象存取器属性:getter和setter介绍
Dec 08 Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
Nov 15 Javascript
原生js和jQuery实现淡入淡出轮播效果
Dec 25 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
May 25 Javascript
关于数据与后端进行交流匹配(点亮星星)
Aug 03 Javascript
jQuery ajax实现省市县三级联动
Mar 07 Javascript
js实现移动端轮播图
Dec 21 Javascript
javascript中undefined的本质解析
Jul 31 Javascript
JS中with的替代方法与String中的正则方法详解
Dec 23 #Javascript
Bootstrap源码解读排版(1)
Dec 23 #Javascript
简单实现JS倒计时效果
Dec 23 #Javascript
Bootstrap源码解读下拉菜单(4)
Dec 23 #Javascript
jquery dataview数据视图插件使用方法
Dec 23 #Javascript
基于vue的下拉刷新指令和滚动刷新指令
Dec 23 #Javascript
Bootstrap源码解读按钮(5)
Dec 23 #Javascript
You might like
同台服务器使用缓存APC效率高于Memcached的演示代码
2010/02/16 PHP
PHP函数学习之PHP函数点评
2012/07/05 PHP
php获取新浪微博数据API实例
2013/11/12 PHP
php实现转换ubb代码的方法
2015/06/18 PHP
PHP仿微信发红包领红包效果
2016/10/30 PHP
PHP观察者模式示例【Laravel框架中有用到】
2018/06/15 PHP
PHP使用XMLWriter读写xml文件操作详解
2018/07/31 PHP
php成功操作redis cluster集群的实例教程
2019/01/13 PHP
javascript实现划词标记+划词搜索功能
2007/03/06 Javascript
filemanage功能中用到的lib.js
2007/04/08 Javascript
js正确获取元素样式详解
2009/08/07 Javascript
javascript 客户端验证上传图片的大小(兼容IE和火狐)
2009/08/15 Javascript
JavaScript定时器详解及实例
2013/08/01 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
jQuery调用RESTful WCF示例代码(GET方法/POST方法)
2014/01/26 Javascript
JavaScript中使用数组方法汇总
2016/02/16 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
easyui 中的datagrid跨页勾选问题的实现方法
2017/01/18 Javascript
Vue实现点击后文字变色切换方法
2018/02/11 Javascript
刷新页面后让控制台的js代码继续执行
2019/09/20 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
儿童python练习实例
2018/05/27 Python
利用python实现在微信群刷屏的方法
2019/02/21 Python
利用 Python ElementTree 生成 xml的实例
2020/03/06 Python
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
利用HTML5画出一个坦克的形状具体实现代码
2013/06/20 HTML / CSS
世界领先的以旅馆为主的在线预订平台:Hostelworld
2016/10/09 全球购物
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
Python中pass语句的作用是什么
2016/06/01 面试题
优秀女职工事迹材料
2014/02/06 职场文书
课例研修方案
2014/05/31 职场文书
2015年党支部书记工作总结
2015/05/21 职场文书
如何才能写好调研报告?
2019/07/03 职场文书
2019客服个人年终工作总结范文
2019/07/08 职场文书
话题作文之学会尊重
2019/12/16 职场文书