Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
haizhilin2013 opened this issue Apr 24, 2019 · 52 comments
Open

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

haizhilin2013 opened this issue Apr 24, 2019 · 52 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

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

@haizhilin2013 haizhilin2013 added the js JavaScript label Apr 24, 2019
@qqdnnd
Copy link

qqdnnd commented May 16, 2019

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

@myprelude
Copy link

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

@Damon99999
Copy link

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

@MartinsYong
Copy link

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

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

@bWhirring
Copy link

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

@Konata9
Copy link

Konata9 commented Jul 5, 2019

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

@Vi-jay
Copy link

Vi-jay commented Jul 25, 2019

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

@NeverLoseYourWay
Copy link

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

@15190408121
Copy link

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

@fanqingyun
Copy link

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

@J1nvey
Copy link

J1nvey commented Sep 6, 2019

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

@careteenL
Copy link

careteenL commented Sep 6, 2019

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
}

@xcLtw
Copy link

xcLtw commented Sep 11, 2019

有几个小问题

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

@censek
Copy link

censek commented Oct 10, 2019

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

@huangpeng0428
Copy link

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

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

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

@YeChang
Copy link

YeChang commented Dec 22, 2019

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

@yyz841875845
Copy link

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

@kruzabc
Copy link

kruzabc commented Dec 24, 2019

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

@rni-l
Copy link

rni-l commented Jan 12, 2020

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

@susanforme
Copy link

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

@xiaoyucoding
Copy link

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

@qiqingfu
Copy link

qiqingfu commented Apr 3, 2020

我个人常用的

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

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

@larry0442
Copy link

我个人常用的

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

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

@blueRoach
Copy link

Object.prototype.toString.call()

@13168335674
Copy link

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

@giggleCYT
Copy link

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

        }

@Alex-Li2018
Copy link

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

@allenGKC
Copy link

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

@MrZ2019
Copy link

MrZ2019 commented Sep 3, 2020

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

@wangzhangbo5916
Copy link

wangzhangbo5916 commented Sep 22, 2020

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

@cool-delete
Copy link

有几个小问题

  • Object.prototype.toString 这里的toStringtoString()的区别是啥,toString()是原生对象提供的方法的话,如何描述toString

加括号是执行啊.不加只是引用而已

  • ([]).toString //ƒ toString() { [native code] } 在浏览器控制台输入的这个返回,表示toString被理解成一个函数,里面的native code又表示什么呢,是代表了原生Object上的部分还是重写之后的

机器码

@xcLtw

@maxthonl
Copy link

maxthonl commented Oct 26, 2020

let x = ''; // null和undefined要单独处理
x.__proto__.constructor.toString()

获取构造函数的方式可以处理自定义类的情况 比如 new Person()

@githubzml
Copy link

看来 我是对题目有误解
typeof()
instanceof()
Object.prototype.toString.call()

@zebratt
Copy link

zebratt commented Jan 14, 2021

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

@GodEnd
Copy link

GodEnd commented Mar 21, 2021

const a = "sdfsd";
const b = function a(){};
const c = 12;
const d = true;
let e;
function judgeType(str) {
// typeof 返回原始数据类型
// return typeof(str);
//Object.prototype.toString.call(str)方法返回Str的类型
return Object.prototype.toString.call(str).substring(8,Object.prototype.toString.call(str).length - 1);
}
console.log(judgeType(a));

@xiezhenghua123
Copy link

function judge(targe) {
return Object.prototype.toString.call(targe).match(/[\w]+/g)[1];
}

@378406712
Copy link

function judge(type){
return Object.prototype.toString.call(type)
}

@WormNimaya
Copy link

WormNimaya commented May 7, 2021

function myType(v){
return Object.prototype.toString.call(v).replace(/([|]|object|\s)/g,'')
}
var a = 11
var b = 'wormnimaya'
var c = true
var d = [0,1,2,3]
var e = {
a:1,
b:1
}
var f=Symbol(0)
var g
var h =null
console.log(myType(a)) // Number
console.log(myType(b)) // String
console.log(myType(c)) // Boolean
console.log(myType(d)) // Array
console.log(myType(e)) // Object
console.log(myType(f)) // Symbol
console.log(myType(g)) // Undefined
console.log(myType(h)) // Null

@HNHED
Copy link

HNHED commented Sep 2, 2021

<script> //基本数据类型 //string、number、null、undefined、boolean //复杂数据类型 //object //新加的两种 bigInt Symbol //对于string、number、null、undefined、boolean、symbol、function来说,使用typeof可以检测出数据类型 console.log(typeof 'aaa'); //string console.log(typeof 1); //number console.log(typeof null); //object console.log(typeof undefined); //undefined console.log(typeof true); //boolean console.log(typeof {}); //object console.log(typeof []); //object console.log(typeof function(){}); //function console.log(typeof new Date()); //object console.log(typeof Symbol('id')); //symbol //但是对于array、date、null来说,typeof不能够检测出它的类型 //但是可以通过object原型上的toString方法来检测它们的类型 function check(str){ let res = Object.prototype.toString.call(str).split(' ')[1]; let res1 = res.substring(0,res.length-1).toLowerCase(); return res1; } console.log(check([])); //array console.log(check(new Date())); //date console.log(check(null)); //null console.log(check(Symbol('id'))); console.log(check(function(){})); console.log(check(undefined)); </script>

@amikly
Copy link

amikly commented Oct 27, 2021

实现

function typeCheck(obj) {
    return Object.prototype.toString.call(obj).replace(/\[object\s|\]/g, "");
}
console.log(typeCheck("aaa"));
console.log(typeCheck(123));
console.log(typeCheck([]));
console.log(typeCheck({}));
console.log(typeCheck(undefined));
console.log(typeCheck(null));
console.log(typeCheck(() => {}));
console.log(typeCheck(new Map()));
console.log(typeCheck(new Set()));

@KarmaLost
Copy link

function typeCheck(obj) {
return Object.prototype.toString.call(obj).split(" ").pop().replace("]", "");
}

@github-cxtan
Copy link

function MyTypeof(data){
let str = Object.prototype.toString.call(data);
return str.slice('[object '.length, str.length-1);
}

@sup194
Copy link

sup194 commented Feb 23, 2022

function checkType(type) {
const tmp = Object.prototype.toString.call(type)
return tmp.slice(8, tmp.length - 1)
}

@yxllovewq
Copy link

const type = data => Object.prototype.toString.call(data).match(/(\w+)]/)[1];

@syfine
Copy link

syfine commented Apr 12, 2022

  • typeof :只能区分number string undefined boolean object五种,不能区分数组和对象
  • Object.prototype.toString.call(null)

@wenxd
Copy link

wenxd commented May 21, 2022

  function judgeDataType(data) {
    let type = Object.prototype.toString.call(data)
    let res = type.slice(8, type.length-1)
    console.log(res);
  }
  judgeDataType(new Date())

@xiaoqiangz
Copy link

// 判断对象类型
function getObjType(obj) {
let types = Object.prototype.toString.call(obj)
return types.slice(8, types.length-1).toLowerCase()
}
console.log(getObjType(11))
console.log(getObjType('11'))
console.log(getObjType(true))
console.log(getObjType([]))
console.log(getObjType({}))

@xiaoxiaozhiya
Copy link

对于基本的数据类型

  • typeof

typeof不能区分null和object,object和array

  • 判断数组用Array.prototype.isArray
  • 判断对象用 A instanceof B
  • 或者用Object.prototype.toString.call()——返回的是一个用中括号包围的字符串

@mohaixiao
Copy link

mohaixiao commented Jun 22, 2022

function typeOf(value) {
    let type = Object.prototype.toString.call(value).slice(8,-1).toLowerCase()
    if(type.match(/^(function | undefined | number | symbol | string | bigint)$/)) return type
    return 'object'
}

可以检查所有的类型

function type(obj, fullClass) {

    // get toPrototypeString() of obj (handles all types)
    // Early JS environments return '[object Object]' for null, so it's best to directly check for it.
    // 早期JS环境 检测 null 返回'[object object]',所以最好直接检查它。
    if (fullClass) {
        return (obj === null) ? '[object Null]' : Object.prototype.toString.call(obj); // 输出[object,xxxx]
    }
    if (obj == null) { return (obj + '').toLowerCase(); } // implicit toString() conversion 隐式toString()转换

    var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
    if (deepType === 'generatorfunction') { return 'function' }

    // Prevent overspecificity (for example, [object HTMLDivElement], etc).
    // 防止过度特异性(例如,[object HTMLDivElement]等)。
    // Account for functionish Regexp (Android <=2.3), functionish <object> element (Chrome <=57, Firefox <=52), etc. 
    // 解释功能化Regexp (Android <=2.3),功能化<对象>元素(Chrome <=57, Firefox <=52),等等。
    // String.prototype.match is universally supported. 
    // 普遍支持String.prototype.match。

    return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :
       (typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
  }

  let user = {
    [Symbol.toStringTag]: "User"
  };
  
 console.log(type(user,false)); // object 有效的防止了过度特异性
 console.log(type(user,true)); // [object User]

@wyy-g
Copy link

wyy-g commented Sep 9, 2022

function getDataType(value){
return {}.String.call(value).replace(/object|\s|[|]/, '');
}

@wuder-jie
Copy link

 function type(target) {
        return Object.prototype.toString
          .call(target)
          .split(" ")[1]
          .replace("]", "");
      }
      console.log(type(12));
      console.log(type("12"));
      console.log(type({ a: 10 }));
      console.log(type([1, 2]));

@lili-0923
Copy link

function checkType(o) {
const match = Object.prototype.toString.call(o).match(/\w+(?=])/);
return match ? match[0].toLowerCase() : "unknown";
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests