Skip to content

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

Open
@haizhilin2013

Description

@haizhilin2013
Collaborator

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

Activity

qqdnnd

qqdnnd commented on May 16, 2019

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

myprelude commented on Jun 13, 2019

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

Damon99999 commented on Jun 18, 2019

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

MartinsYong commented on Jun 25, 2019

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

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

bWhirring commented on Jul 3, 2019

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

Konata9 commented on Jul 5, 2019

@Konata9

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

Vi-jay commented on Jul 25, 2019

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

NeverLoseYourWay commented on Aug 9, 2019

@NeverLoseYourWay

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

15190408121

15190408121 commented on Aug 25, 2019

@15190408121

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

fanqingyun

fanqingyun commented on Sep 2, 2019

@fanqingyun

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

J1nvey

J1nvey commented on Sep 6, 2019

@J1nvey
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

careteenL commented on Sep 6, 2019

@careteenL

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

xcLtw commented on Sep 11, 2019

@xcLtw

有几个小问题

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

40 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    jsJavaScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @smile-2008@haizhilin2013@allenGKC@zebratt@Konata9

        Issue actions

          [js] 第9天 写一个判断数据类型的方法 · Issue #27 · haizlin/fe-interview