实现类型判断-创新互联
本节我们来挑战一道大厂面试真题 —— 实现类型判断。
成都创新互联服务项目包括通江网站建设、通江网站制作、通江网页制作以及通江网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,通江网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到通江省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!挑战准备新建一个getType.js
文件,在文件里写一个名为getType
的函数,并导出这个函数,如下图所示:
这个文件在环境初始化时会自动生成,如果发现没有自动生成就按照上述图片自己创建文件和函数,函数代码如下:
function getType(target) {// 补充代码
}
module.exports = getType;
挑战内容请封装一个函数,能够以字符串的形式精准地返回数据类型。
要求返回的类型全部由小写字母组成。
示例:
输入 | 输出 |
---|---|
true | ‘boolean’ |
100 | ‘number’ |
‘abc’ | ‘string’ |
100n | ‘bigint’ |
null | ‘null’ |
undefined | ‘undefined’ |
Symbol(‘a’) | ‘symbol’ |
[] | ‘array’ |
{} | ‘object’ |
function fn() {} | ‘function’ |
new Date() | ‘date’ |
/abc/ | ‘regexp’ |
new Error() | ‘error’ |
new Map() | ‘map’ |
new Set() | ‘set’ |
new WeakMap() | ‘weakmap’ |
new WeakSet() | ‘weakset’ |
- 文件名、函数名不可随意更改。
- 文件中编写的函数需要导出,否则将无法提交通过。
先贴一波答案
function getType(target) {const type = typeof target;
if (type !== "object") {return type;
}
return Object.prototype.toString
.call(target)
.replace(/^\[object (\S+)\]$/, "$1")
.toLocaleLowerCase();
}
首先我们要知道javascrip数据类型有两种:
基本类型:Undefined,Null,Boolean,Number,String
引用类型:
第一类:原生对象:object,Array,Date,RegExp,Function以及有基本类型衍生出来的包装类型Boolean,Number,String;
第二类内置对象,如Global,Math
宿主对象,如IE中的window,WS中的WScript实例,以及任何用户创建的类
判断一个数据的类型,比较常用的有下面几种方式:
typeof
instanceof
Object.prototype.toString.call(xxx)
判断一个数据的类型,用得最多的就是 typeof 操作符, 但是使用typeof
常常会遇到以下问题:
- 无法判断
null
。 - 无法判断除了
function
之外的引用类型。
// 可以判断除了 null 之外的基础类型。
console.log(typeof true);// boolean
console.log(typeof 100);// number
console.log(typeof "abc");// String
console.log(typeof 100n);// bigint
console.log(typeof undefined);// undefined
console.log(typeof Symbol("a"));// symbol
// 无法判断 null function 之外的引用类型。
console.log(typeof null);// object
console.log(typeof []);// object
console.log(typeof {});// object
const fn = function(){};
console.log(typeof fn);// function
typeof
无法精确地判断引用类型,这时,可以使用 instanceof 运算符,但是instanceof
运算符一定要是判断对象实例的时候才是正确的
console.log([] instanceof Array);// true
const obj = {};
console.log(obj instanceof Object);// true
const fn = function(){};
console.log(fn instanceof Function);// true
const date = new Date();
console.log(date instanceof Date);// true
const re = /abc/;
console.log(re instanceof RegExp);// true
const str1 = "qwe";
const str2 = new String("qwe");
console.log(str1 instanceof String); // false,无法判断原始类型。
console.log(str2 instanceof String); // true
null比较特殊,可以直接判断
function getType(target) {// ...
if (target === null) {return "null";
}
// ...
}
调用Object.prototype.toString
方法,会统一返回格式为[object Xxx]
的字符串,用来表示该对象(原始类型是包装对象)的类型。
// 引用类型 以此类推
console.log(Object.prototype.toString.call({})); // '[object Object]'
console.log(Object.prototype.toString.call(function () {})); // "[object Function]'
console.log(Object.prototype.toString.call(/123/g)); // '[object RegExp]'
console.log(Object.prototype.toString.call(new Date())); // '[object Date]'
console.log(Object.prototype.toString.call([])); // '[object Array]'
console.log(Object.prototype.toString.call(new WeakSet())); // '[object WeakSet]'
// 原始类型 以此类推
console.log(Object.prototype.toString.call(1)); // '[object Number]'
console.log(Object.prototype.toString.call("abc")); // '[object String]'
Object.prototype.toString
方法来获取数据具体的类型,然后把多余的字符去掉即可,只取[object Xxx]
里的Xxx
。
所以最终的代码实现为
function getType(target) {// 先进行 typeof 判断,如果是基础数据类型,直接返回。
const type = typeof target;
if (type !== "object") {return type;
}
// 如果是引用类型或者 null,再进行如下的判断,正则返回结果,注意最后返回的类型字符串要全小写。
return Object.prototype.toString
.call(target)
.replace(/^\[object (\S+)\]$/, "$1")
.toLocaleLowerCase();
}
或者返回
// ...
return Object.prototype.toString
.call(target)
.match(/\s([a-zA-Z]+)\]$/)[1] // 这种写法也可以。
.toLocaleLowerCase();
不用正则表达式也可以哦
// ...
return Object.prototype.toString
.call(target)
.slice(8, -1)
//slice(startIndex,endIndex),从0开始索引,其中8代表从第8位(包含)开始截取(本例中代表空格后面的位置,'['也是代表一位,不要看少了哦),-1代表截取到倒数第一位(不含),所以正好截取到[object String]中的String。
.toLocaleLowerCase();
call 是函数的方法,是用来改变 this 指向的,用 apply 方法也可以。
如果不改变this
指向为我们的目标变量xxx
,this
将永远指向调用的Object.prototype
,也就是原型对象,对原型对象调用toString
方法,结果永远都是[object Object]
console.log(Object.prototype.toString([]));
// 输出 '[object Object]' 不调用 call,this 指向 Object.prototype,判断类型为 Object。
console.log(Object.prototype.toString.call([]));
// 输出 '[object Array]' 调用 call,this 指向 [],判断类型为 Array
最后加几个学到的常见的js面试问题
1:JavaScript 有哪些数据类型答: JavaScript 的数据类型分为原始类型和对象类型。
原始类型有 7 种,分别是:
- Boolean
- Number
- BigInt
- String
- Null
- Undefined
- Symbol
对象类型(也称引用类型)是一个泛称,包括数组、对象、函数等一切对象。
常见面试题 2:typeof null 的结果是什么答:
typeof null; // 'object'
常见面试题 3:原始类型和引用类型的区别是什么答:
类型 | 原始类型 | 对象类型 |
---|---|---|
值 | 不可改变 | 可以改变 |
属性和方法 | 不能添加 | 能添加 |
存储值 | 值 | 地址(指针) |
比较 | 值的比较 | 地址的比较 |
答:
typeof
运算符用来判断数据的类型。- instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上,也可以用来判断数据的类型。
typeof
返回一个变量的类型字符串,instanceof
返回的是一个布尔值。typeof
可以判断除了null
以外的基础数据类型,但是判断引用类型时,除了function
类型,其他的无法准确判断。instanceof
可以准确地判断各种引用类型,但是不能正确判断原始数据类型。
答:Symbol
是 ES6 时新增的特性,Symbol
是一个基本的数据类型,表示独一无二的值,主要用来防止对象属性名冲突问题。
const obj = {name: "song",
age: 18,
};
obj.name = "xxx"; // 给 obj.name 赋值,把以前的 name 覆盖了
console.log(obj); // { name: 'xxx', age: 18 }
copy
const obj = {name: "song",
age: 18,
};
const name = Symbol("name");
obj[name] = "xxx"; // 使用 Symbol,不会覆盖
console.log(obj); // { name: 'song', age: 18, Symbol(name): 'xxx' }
console.log(obj.name); // 'song'
console.log(obj[name]); // 'xxx'
挑战总结- 这个题之前几次测试都没过,因为还不是很理解原始类型和对象类型的类型判断的方法
- Bigint和symbol也不熟悉,感觉第一次看到,不清楚他们是哪一种类型的数据
- 对instanceof的使用也不够熟练
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站标题:实现类型判断-创新互联
文章路径:http://myzitong.com/article/dcsjoe.html