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 相关文章推荐
通过url查找a元素并点击
Apr 09 Javascript
AngularJS入门教程之Hello World!
Dec 06 Javascript
JavaScript中join()方法的使用简介
Jun 09 Javascript
jQuery语法小结(超实用)
Dec 31 Javascript
基于JQuery实现分隔条的功能
Jun 17 Javascript
jQuery简单获取DIV和A标签元素位置的方法
Feb 07 Javascript
js实现下拉框效果(select)
Mar 28 Javascript
详解微信小程序审核不通过的解决方法
Jan 17 Javascript
Angular服务Request异步请求的实例讲解
Aug 13 Javascript
vscode 使用Prettier插件格式化配置使用代码详解
Aug 10 Javascript
JS页面动态绘图工具SVG,Canvas,VML介简介
Oct 16 Javascript
JavaScript实现网页动态生成表格
Nov 25 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
图书管理程序(二)
2006/10/09 PHP
浅析PHP安装扩展mcrypt以及相关依赖项(PHP安装PECL扩展的方法)
2013/07/05 PHP
微信公众平台网页授权获取用户基本信息中授权回调域名设置的变动
2014/10/21 PHP
php上传文件并存储到mysql数据库的方法
2015/03/16 PHP
PDO::quote讲解
2019/01/29 PHP
php更新cookie内容的详细方法
2019/09/30 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
IE autocomplete internet explorer's autocomplete
2007/06/30 Javascript
兼容IE/Firefox/Opera/Safari的检测页面装载完毕的脚本Ext.onReady的实现
2009/07/14 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
2011/04/26 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
js 异步操作回调函数如何控制执行顺序
2013/12/24 Javascript
JavaScript高级教程5.6之基本包装类型(详细)
2015/11/23 Javascript
javascript模块化简单解析
2016/04/07 Javascript
使用AJAX实现Web页面进度条的实例分享
2016/05/06 Javascript
基于bootstrap的文件上传控件bootstrap fileinput
2016/12/23 Javascript
a标签置灰不可点击的实现方法
2017/02/06 Javascript
原生js实现可拖拽效果
2017/02/28 Javascript
Bootstrap表格制作代码
2017/03/17 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
2017/08/31 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
Vue 中使用 typescript的方法详解
2020/02/17 Javascript
javascript实现图片轮换动作方法
2020/08/07 Javascript
JavaScript array常用方法代码实例详解
2020/09/02 Javascript
Python中unittest模块做UT(单元测试)使用实例
2015/06/12 Python
你眼中的Python大牛 应该都有这份书单
2017/10/31 Python
Python利用turtle库绘制彩虹代码示例
2017/12/20 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
python实现动态数组的示例代码
2019/07/15 Python
Python 字典一个键对应多个值的方法
2020/09/29 Python
用Python制作音乐海报
2021/01/26 Python
求职简历的自我评价怎样写好
2013/10/07 职场文书
《与象共舞》教学反思
2014/02/24 职场文书
工作证明范本(2篇)
2014/09/14 职场文书
投诉书格式范本
2015/07/02 职场文书
教你如何让spark sql写mysql的时候支持update操作
2022/02/15 MySQL