fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

[js] 第9天 写一个判断数据类型的方法

Open haizhilin2013 opened this issue 6 years ago • 53 comments

第9天 写一个判断数据类型的方法

haizhilin2013 avatar Apr 24 '19 20:04 haizhilin2013

function myType(v){
    return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase());
}

qqdnnd avatar May 16 '19 10:05 qqdnnd

  • typeof
    不能判读 数组 和 对象
  • toString()
Object.prototype.toString.call([])  //"[object Array]"
Object.prototype.toString.call({})  //"[object Object]"

myprelude avatar Jun 13 '19 08:06 myprelude

toString.call() // "Array", "Function", "Object", "RegExp", "Date"
typeof obj // "Boolean", "Number", "String"

Damon99999 avatar Jun 18 '19 07:06 Damon99999

function type (obj) {
	return Object.prototype.toString.call(obj).replace(/\[object\s|\]/g,'');
}

console.log(type([]))  //"Array"
console.log(type(1))  //"Number"

MartinsYong avatar Jun 25 '19 08:06 MartinsYong

 function isType(obj) {
    return (type) => {
        return Object.prototype.toString.call(obj) === `[object ${type}]`
    }
}

bWhirring avatar Jul 03 '19 03:07 bWhirring

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])));

Konata9 avatar Jul 05 '19 08:07 Konata9

function isTypeOf(obj, type) {
  return Object.prototype.toString.call(obj)
    .replace(/[\[|\]]/g, "")
    .substr(7).toLowerCase() === type.toLowerCase();
}

Vi-jay avatar Jul 25 '19 08:07 Vi-jay

function myType(v){ return Object.prototype.toString.call(v).replace(/^.{8}(.+)]$/,(m,$1)=> $1.toLowerCase()); } 请问这个正则是什么意思

NeverLoseYourWay avatar Aug 09 '19 02:08 NeverLoseYourWay

function types (obj) { return Object.prototype.toString.call(obj).replace(/[object\s|]/g, ''); } console.log(type({})) console.log(type(1)) console.log(type([]))

15190408121 avatar Aug 25 '19 09:08 15190408121

function getType(target){ let rs = Object.prototype.toString.call(target).split(' ') return rs[1].substr(0, rs[1].length-1) }

fanqingyun avatar Sep 02 '19 07:09 fanqingyun

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

J1nvey avatar Sep 06 '19 06:09 J1nvey

typeof不足

❌众所周知原生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,可前往查看支持类型以及测试用例。

下面写法支持

  • number, boolean, string, undefined, null, symbol
  • array, object, set, weakset, map, weakmap
  • function, class
  • regexp, date, math, promise
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
}

careteenL avatar Sep 06 '19 07:09 careteenL

有几个小问题

  • Object.prototype.toString 这里的toStringtoString()的区别是啥,toString()是原生对象提供的方法的话,如何描述toString
  • ([]).toString //ƒ toString() { [native code] } 在浏览器控制台输入的这个返回,表示toString被理解成一个函数,里面的native code又表示什么呢,是代表了原生Object上的部分还是重写之后的
  • (10).toString(2) // '1010' 不同的数据类型带有的toString()是有区别的,特别是数字型的可以做进位转换

xcLtw avatar Sep 11 '19 02:09 xcLtw

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

censek avatar Oct 10 '19 01:10 censek

const isType = (targe, type) => { if(typeof targe !== 'object') return const typeString = Object.prototype.toString.call(targe)

return `[object ${type}]` === typeString

} isType([], 'Array') //true

huangpeng0428 avatar Oct 21 '19 16:10 huangpeng0428

//第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"));

YeChang avatar Dec 22 '19 08:12 YeChang

Object.prototype.toString.call() 将目标转换成[object Null] 这种形式,然后截取

yyz841875845 avatar Dec 23 '19 02:12 yyz841875845

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), 匹配出来的字符串。

kruzabc avatar Dec 24 '19 03:12 kruzabc

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

rni-l avatar Jan 12 '20 07:01 rni-l

var obj={age:18},str="hello",num=18,ary=[0,1,2];
var checkType=v=> Object.prototype.toString.call(v).replace(/object |\[|\]/g,"");

susanforme avatar Feb 04 '20 06:02 susanforme

function getType(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

xiaoyucoding avatar Mar 19 '20 05:03 xiaoyucoding

我个人常用的

// 写一个判断类型的方法

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
 */

qiqingfu avatar Apr 03 '20 14:04 qiqingfu

我个人常用的

// 写一个判断类型的方法

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就完美了

larry0442 avatar Apr 07 '20 06:04 larry0442

Object.prototype.toString.call()

blueRoach avatar May 26 '20 02:05 blueRoach

const getType = target => Object.prototype.toString.call(target).toLowerCase().slice(8,-1);

13168335674 avatar May 29 '20 02:05 13168335674

        function fn(obj) {
            if (typeof(obj) == 'object') {
                return Object.prototype.toString.call(obj).replace(/\[|object|\s|\]/g, '')
            }
            return typeof(obj);

        }

giggleCYT avatar Jun 03 '20 04:06 giggleCYT

// 类型检测偏函数 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');

Alex-Li2018 avatar Jul 28 '20 09:07 Alex-Li2018

function myType(v){ return Object.prototype.toString.call(v).substr(8,).split(']')[0].toLowerCase() }

allenGKC avatar Aug 28 '20 07:08 allenGKC

toString.call() // "Array", "Function", "Object", "RegExp", "Date" typeof obj // "Boolean", "Number", "String"

smile-2008 avatar Sep 03 '20 09:09 smile-2008

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() {}));

wangzhangbo5916 avatar Sep 22 '20 15:09 wangzhangbo5916