第9天 写一个判断数据类型的方法
function myType(v){ return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase()); }
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call({}) //"[object Object]"
toString.call() // "Array", "Function", "Object", "RegExp", "Date"
typeof obj // "Boolean", "Number", "String"
function type (obj) {
return Object.prototype.toString.call(obj).replace(/\[object\s|\]/g,'');
}
console.log(type([])) //"Array"
console.log(type(1)) //"Number"
function isType(obj) {
return (type) => {
return Object.prototype.toString.call(obj) === `[object ${type}]`
}
}
typeof
只能判断基本类型 string
,number
,boolean
, undefined
,object
null
会被判断成 object
比较全面的是使用 Object.prototype.toString
方法,只需要对返回值进行字符串分割即可
const typeCheck = (obj) => {
const typeStr = Object.prototype.toString.call(obj);
return typeStr.toLowerCase().slice(8, typeStr.length - 1);
};
console.log(typeCheck("str"));
console.log(typeCheck(1));
console.log(typeCheck(() => null));
console.log(typeCheck({a: 1}));
console.log(typeCheck([1, 2, 3]));
console.log(typeCheck(new Set([1,2,3])));
function isTypeOf(obj, type) {
return Object.prototype.toString.call(obj)
.replace(/[\[|\]]/g, "")
.substr(7).toLowerCase() === type.toLowerCase();
}
function myType(v){
return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase());
}
请问这个正则是什么意思
function types (obj) {
return Object.prototype.toString.call(obj).replace(/[object\s|]/g, '');
}
console.log(type({}))
console.log(type(1))
console.log(type([]))
function getType(target){
let rs = Object.prototype.toString.call(target).split(' ')
return rs[1].substr(0, rs[1].length-1)
}
const getDataType = el => {
const dataType = Object.prototype.toString.call(el);
return dataType.split(' ')[1].split(']')[0];
};
console.log(getDataType(123)); // Number
console.log(getDataType('123')); // String
console.log(getDataType(() => { })); // Function
console.log(getDataType([1, 2, 3])); // Array
❌众所周知原生typeof
有很多不足如下所示:
typeof null // object
typeof /a/ // object
typeof new String('') // object
function A () {}
typeof (new A) // 'object'
✅我们期望能返回下面:
import type from '@careteen/type'
type(null) // null
type(/a/) // regexp
type(new String('')) // string
function A () {}
type(new A) // A
将功能封装在@careteen/type,可前往查看支持类型以及测试用例。
下面写法支持
const _toString = Object.prototype.toString
const NULL = 'null'
const OBJECT = 'object'
const NUMBER = 'number'
const BOOLEAN = 'boolean'
const STRING = 'string'
const UNKNOW = 'unknow'
/**
*
* @param {*} element 任意类型的变量
* @param {Boolean} strict [default: false] 是否为严格模式
* @return {String} 变量的真实类型
*/
export default function type (element, strict = false) {
strict = !!strict
// #1 fix typeof null === 'object'
if (element === null) {
return NULL
}
const eleType = typeof element
// #2 return [number string boolean undefined symbol]
if (eleType !== OBJECT) {
return eleType
}
let eleRealType
let eleRealTypeLower
try {
eleRealType = _toString.call(element).slice(8, -1)
eleRealTypeLower = eleRealType.toLowerCase()
} catch (e) {
// #3 IE activie 对象
return OBJECT
}
// #4 fix typeof new String('') === 'object' , expect 'string'
if (eleRealTypeLower !== OBJECT) {
// 严格模式下 会严格区分`number、string、boolean`的原始值和对象值
// example `new String('') => 'String'`、`String('') => 'string'`
if (strict && (eleRealTypeLower === NUMBER || eleRealTypeLower === BOOLEAN || eleRealTypeLower === STRING)) {
return eleRealType
}
return eleRealTypeLower
}
if (element.constructor == Object) {
return eleRealTypeLower
}
// #5 Object.create(null)
try {
// __proto__ 为部分早期浏览器
if (Object.getPrototypeOf(element) === NULL || element.__proto__ === NULL) {
return OBJECT
}
} catch (e) {
// IE 无 Object.getPrototypeOf
}
// #6 function A () {}; new A
try {
const constructorName = element.constructor.name
if (typeof constructorName === STRING) {
return constructorName
}
} catch (e) {
// No constructor
}
// function A() {}; A.prototype.constructor = null; new A
return UNKNOW
}
有几个小问题
Object.prototype.toString
这里的toString
和toString()
的区别是啥,toString()
是原生对象提供的方法的话,如何描述toString
呢([]).toString //ƒ toString() { [native code] }
在浏览器控制台输入的这个返回,表示toString
被理解成一个函数,里面的native code又表示什么呢,是代表了原生Object
上的部分还是重写之后的(10).toString(2) // '1010'
不同的数据类型带有的toString()
是有区别的,特别是数字型的可以做进位转换function myType(v){
return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase());
}
请问这个正则是什么意思
console.log(Object.prototype.toString.call("abc")); // [object String]
可以看到,对于打印的结果,前8个字符我们不要,并且需要将类型结果转换为小写的 string
const isType = (targe, type) => {
if(typeof targe !== 'object') return
const typeString = Object.prototype.toString.call(targe)
return `[object ${type}]` === typeString
}
isType([], 'Array') //true
//第9天 写一个判断数据类型的方法
function type(obj) {
return Object.prototype.toString
.call(obj)
.split(" ")[1]
.replace("]", "");
}
console.log(type([]));
console.log(type({}));
console.log(type(() => {}));
console.log(type(1));
console.log(type("1"));
Object.prototype.toString.call() 将目标转换成[object Null] 这种形式,然后截取
function type(obj) {
return /^\[object (\w*)]$/.test(Object.prototype.toString.call(obj)) ? RegExp.$1 : 'unknown';
}
console.log(type('hello'));
console.log(type(1));
console.log(type(Number(1)));
console.log(type({}));
console.log(type([]));
console.log(type(new Date()));
console.log(type(Symbol()));
console.log(type(new RegExp()));
console.log(type(Math));
console.log(type(window));
console.log(type(null));
console.log(type(undefined));
console.log(type(new Error()));
console.log(type(Promise));
返回正则提取Object.prototype.toString.call(obj)
, 匹配出来的字符串。
function checkType(val) {
return Object.prototype.toString.call(val).replace(/(\[object)|\]/g, '').toLowerCase()
}
console.log(checkType('sdf'))
console.log(checkType(123))
console.log(checkType([]))
console.log(checkType({}))
console.log(checkType(undefined))
console.log(checkType(null))
console.log(checkType(() => {}))
// string
// number
// array
// object
// undefined
// null
// function
var obj={age:18},str="hello",num=18,ary=[0,1,2];
var checkType=v=> Object.prototype.toString.call(v).replace(/object |\[|\]/g,"");
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
我个人常用的
// 写一个判断类型的方法
const Type = (function () {
const types = {};
const supperTypes = [
'String',
'Number',
'Boolean',
'Null',
'Undefined',
'Object',
'Function',
'Array',
'Date'
];
for (let type of supperTypes) {
types[`is${type}`] = function (data) {
return Object.prototype.toString.call(data) === `[object ${type}]`;
}
}
return types;
})();
let str = '我是字符串';
let num = 123;
let bol = false;
let arr = [1,2,3];
let obj = {};
let func = class {};
console.log(Type.isString(str));
console.log(Type.isNumber(num));
console.log(Type.isBoolean(bol));
console.log(Type.isArray(arr));
console.log(Type.isObject(obj));
console.log(Type.isFunction(func));
/**
* true
* true
* true
* true
* true
* true
*/
我个人常用的
// 写一个判断类型的方法 const Type = (function () { const types = {}; const supperTypes = [ 'String', 'Number', 'Boolean', 'Null', 'Undefined', 'Object', 'Function', 'Array', 'Date' ]; for (let type of supperTypes) { types[`is${type}`] = function (data) { return Object.prototype.toString.call(data) === `[object ${type}]`; } } return types; })(); let str = '我是字符串'; let num = 123; let bol = false; let arr = [1,2,3]; let obj = {}; let func = class {}; console.log(Type.isString(str)); console.log(Type.isNumber(num)); console.log(Type.isBoolean(bol)); console.log(Type.isArray(arr)); console.log(Type.isObject(obj)); console.log(Type.isFunction(func)); /** * true * true * true * true * true * true */
加上Symbol和BigInt就完美了
Object.prototype.toString.call()
const getType = target => Object.prototype.toString.call(target).toLowerCase().slice(8,-1);
function fn(obj) {
if (typeof(obj) == 'object') {
return Object.prototype.toString.call(obj).replace(/\[|object|\s|\]/g, '')
}
return typeof(obj);
}
// 类型检测偏函数
const toString = Object.prototype.toString;
function isType (type) {
return function(obj) {
return toString.call(obj) === [object ${type}]
;
};
}
const isArray = isType('Array');
const isObject = isType('Object');
const isString = isType('String');
const isNull = isType('Null');
function myType(v){
return Object.prototype.toString.call(v).substr(8,).split(']')[0].toLowerCase()
}
toString.call() // "Array", "Function", "Object", "RegExp", "Date"
typeof obj // "Boolean", "Number", "String"
function getDataType(data) {
return Object.prototype.toString.call(data).replace(/\[object\s+(\w+)\]/i, (match, $1) => {
console.log(match, $1);
return $1.toLocaleLowerCase();
});
}
console.log(getDataType(1));
console.log(getDataType(''));
console.log(getDataType(true));
console.log(getDataType(null));
console.log(getDataType(undefined));
console.log(getDataType(Symbol(1)));
console.log(getDataType({}));
console.log(getDataType([]));
console.log(getDataType(function() {}));
有几个小问题
Object.prototype.toString
这里的toString
和toString()
的区别是啥,toString()
是原生对象提供的方法的话,如何描述toString
呢
加括号是执行啊.不加只是引用而已
([]).toString //ƒ toString() { [native code] }
在浏览器控制台输入的这个返回,表示toString
被理解成一个函数,里面的native code又表示什么呢,是代表了原生Object
上的部分还是重写之后的
机器码
@xcLtw
let x = ''; // null和undefined要单独处理
x.__proto__.constructor.toString()
获取构造函数的方式可以处理自定义类的情况 比如 new Person()
看来 我是对题目有误解
typeof()
instanceof()
Object.prototype.toString.call()
function checkType(o) {
const match = Object.prototype.toString.call(o).match(/\w+(?=\])/);
return match ? match[0].toLowerCase() : "unknown";
}
console.log(checkType({}));
console.log(checkType(123));
console.log(checkType("123"));
console.log(checkType([]));
console.log(checkType(new Map()));
console.log(checkType(function () {}));
console.log(checkType(Symbol()));
console.log(checkType(null));
console.log(checkType(undefined));
/**
object
number
string
array
map
function
symbol
null
undefined
*/
Most helpful comment