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 相关文章推荐
Chrome中模态对话框showModalDialog返回值问题的解决方法
May 25 Javascript
Jquery知识点二 jquery下对数组的操作
Jan 15 Javascript
js 创建书签小工具之理论
Feb 25 Javascript
Javascript表格翻页效果的具体实现
Oct 05 Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 Javascript
Javascript获取图片原始宽度和高度的方法详解
Sep 20 Javascript
jquery dataTable 后台加载数据并分页实例代码
Jun 07 jQuery
JavaScrpt中如何使用 cookie 设置查看与删除功能
Jul 09 Javascript
分享ES6的7个实用技巧
Jan 18 Javascript
Angular数据绑定机制原理
Apr 17 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
Jun 21 Javascript
js中比较两个对象是否相同的方法示例
Sep 02 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
PHP 加密解密内部算法
2010/04/22 PHP
Yii+upload实现AJAX上传图片的方法
2016/07/13 PHP
使用正则去除php代码中的注释方法
2016/11/03 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
PHP实现的微信公众号扫码模拟登录功能示例
2019/05/30 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
JavaScript中的Document文档对象
2008/01/16 Javascript
往光标所在位置插入值的js代码
2013/09/22 Javascript
多引号嵌套的变量命名的问题
2014/05/09 Javascript
jquery和js实现对div的隐藏和显示方法
2014/09/26 Javascript
JS使用eval解析JSON的注意事项分析
2015/11/14 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
单击按钮发送验证码,出现倒计时的简单实例
2017/03/17 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
EasyUI 数据表格datagrid列自适应内容宽度的实现
2019/07/18 Javascript
Vue实现数据表格合并列rowspan效果
2020/11/30 Javascript
详解如何在Javascript和Sass之间共享变量
2019/11/13 Javascript
微信小程序基于movable-view实现滑动删除效果
2020/01/08 Javascript
python实现SMTP邮件发送功能
2020/06/16 Python
python机器学习库常用汇总
2017/11/15 Python
Python中Scrapy爬虫图片处理详解
2017/11/29 Python
人工神经网络算法知识点总结
2019/06/11 Python
python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境
2020/12/14 Python
为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景
2021/01/05 Python
HTML利用九宫格原理进行网页布局
2020/03/13 HTML / CSS
美国特价机票专家:Airfarewatchdog
2018/01/24 全球购物
彪马荷兰官网:PUMA荷兰
2019/05/08 全球购物
Farfetch台湾官网:奢侈品牌时尚购物平台
2019/06/17 全球购物
2013年高中生自我评价
2013/10/23 职场文书
继承公证书
2014/04/09 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
出国留学英文自荐信
2015/03/25 职场文书
2015年宣传部工作总结范文
2015/03/31 职场文书
mysql insert 存在即不插入语法说明
2022/03/25 MySQL
苹果macOS 13开发者预览版Beta 8发布 正式版10月发布
2022/09/23 数码科技