我们都知道JS中包含两种数据类型:基本数据类型和引用数据类型。

基本数据类型:String、Number、Boolean、Null、Undefined、Symbol(ES6新增,表示独一无二的值)

引用数据类型:Object(包含Array、Function、Date、RegExp)

基本数据类型保存的值是直接存储在栈(stack)内存中,而引用数据类型存储在栈内存的是指向堆(heap)内存的引用(或者说指针,而真正的数据是保存在堆内存中的)

从一个变量向另一个变量复制基本数据类型时: 复制的是值本身

var number = 5;
var number_copy = number;
/*number和number_copy中的值是相互独立的,两个变量可以任意操作而不互相影响
*/

从一个变量向另一个变量复制引用数据类型时:复制的是引用

var object = {name: 'ckn', age: 18};
var object_copy = object;
object_copy.name = 'lxh';
/*复制的是引用,复制结束后,两个变量实际上引用的还是同一个对象修改其中任何一个变量,都会影响另外一个变量
*/

我们在日常开发中会经常判断一个数据的类型,是数组类型还是对象类型还是undefined或者null这种特殊的类型

判断基本数据类型,我们可以使用 typeof 很容易得到基本数据类型是什么数据类型,null除外,因为一些js历史遗留问题,null被视为object

function log(target){return console.log(target);
}
log(typeof 110); // number
log(typeof 'hello world'); // string
log(typeof true); // boolean
log(typeof undefined); // undefined
log(typeof null);  // object
log(typeof {name: 'ckn', age: 18}); // object
log(typeof [1,2,3,4]); // object 我们其实期望得到的是array
log(typeof function() {log(1)}) // function
// 我们可以通过 Array.isArray()来判断其是否是数组
// 或者我们也可以 instanceof 来判断属于哪一类对象
log([1,2,3,4] instanceof Array); // true

其实无论用typeof 还是 instanceof 或者是 Array.isArray判断数据的具体类型,都有一定的局限性,很繁琐。让人不禁想问就没有更通用的方法来一次就判断出该数据到底属于什么类型吗?

当然是有这样的方法了,请看下面的代码:

function log(target){return console.log(target);
}
function whatType(target){return Object.prototype.toString.call(target).slice(8, -1);
}
log(whatType(110)); // Number
log(whatType('hello world')); // String
log(whatType(true)); // Boolean
log(whatType({name: 'ckn',age: 18})); // Object
log(whatType([1,2,3,4])); // Array
log(whatType(function(){log(1)})); // Function
log(whatType(undefined));  // Undefined
log(whatType(null)); // Null
log(whatType(/z-Z/)); RegExp
log(whatType(new Date())); // Date

我一开始很不理解为什么调用Object.prototype.toString方法就可以得到某个数据的具体类型,我们来先看下Object.prototype.toString方法 :

MDN :每个对象都有一个toString()方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()方法被每个Object对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中type是对象的类型。

let obj = {name: 'ckn', age: 18}
/*obj是Object构造函数的实例对象 obj.toString方法是继承自Objectconsole.log(obj.toString === Object.prototype.toString);  true
*/
console.log(obj.toString()); // 这个很重要 它打印出的是[object Object]
/*arr是Array构造函数的实例对象 arr.toString方法是继承自Arrayconsole.log(arr.toString === Array.prototype.toString);  true
*/
let arr =  [1,2,3];
console.log(array.toString()); // "1,2,3,4" 字符串形式
/*bar是Function构造函数的实例对象 bar.toString方法是继承自Functionconsole.log(bar.toString === Function.prototype.toString);  true
*/
let bar = function() { console.log('hello world') }
console.log(bar.toString()); // "function() { console.log('hello world') }"// 其实根据MDN的解释,我们还可以自定义obj的toString方法 这样就不会继承来自Object的toString方法了
obj.prototype.toString = function toStringSelf() {return `your name is ${this.name}, your age is ${this.age}`
}
obj.toString(); // your name is ckn, your age is 18/*
console.log(bar.toString);
ƒ (){return"function"==typeof this&&this.__raven__?t._originalFunctionToString.apply(this.__orig__,arguments):t._originalFunctionToString.apply(this,arguments)}
*/

我们知道了Object对象的toString方法调用后可以打印出 "[object Object]" 这个奇怪的东西,Array对象的toString方法调用后是得到字符串形式的每项的值,Function对象的toString方法调用后得到的是该函数对象的整体语句内容和结构

接下来我们分析:

Object.prototype.toString.call(target)

我们知道call方法可以修改函数执行时的上下文对象this指向,此时Object.prototype.toString方法内部的this指的就是传进来的target对象

通过上面的分析,我们发现toString方法除了Object内部实现了,Array、Function、String、Number、Boolean、RegExp、Symbol等构造函数都对其进行了实现 (在各自原型上都有toString方法的实现)

其中有区别的是: Function、Number、String、Date的toString方法规定了函数内部的this指向必须分别是function、number、string、date类型,否则将会报错,例如:

Function.prototype.toString.call({name:'ckn', age:18});
// Uncaught TypeError:Function.prototype.toString requires that 'this' be a FunctionFunction.prototype.toString.call(function() {});
//  "function() {}"Number.prototype.toString.call({name:'ckn', age:18});
// Uncaught TypeError:Number.prototype.toString requires that 'this' be a Number
Number.prototype.toString.call(101);
// "101"

而Array的toString方法内部并没有明确规定函数内部this指向必须是数组类型,可以是任意类型,是数组类型的时候返回的是遍历数组的每一项然后调用toString方法的返回值,但当是null和undefined的时候则会报错

Array.prototype.toString.call(function(){}); // "[object Function]"
Array.prototype.toString.call({name: 'ckn',age: 18}); // "[object Object]"
Array.prototype.toString.call(new Date); // "[object Date]"
Array.prototype.toString.call([1,function(){},{}]); // "1,function(){},[object Object]"Array.prototype.toString.call(undefiend);
// Uncaught TypeError: Cannot convert undefined or null to objectArray.prototype.toString.call(null);
// Uncaught TypeError: Cannot convert undefined or null to object

同样Obiect的toString方法内部也没有明确规定函数内部this指向必须是对象类型,可以是任意数据类型,而且当是null和undefined时也不会报错

Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"Object.prototype.toString.call(function(){}); // "[object Function]"
Object.prototype.toString.call({name: 'ckn',age: 18}); // "[object Object]"
Object.prototype.toString.call(new Date); // "[object Date]"
Object.prototype.toString.call([1,function(){},{}]); // "[object Array]"
Object.prototype.toString.call(/z-Z/); // "[object RegExp]"

ok,到此我们发现了Object的toString方法最牛掰,可以分辨出任何数据类型

function whatType(target) {reutnr Object.prototype.toString.call(target).slice(8, -1);
}

js date转string_JS之你到底是什么类型?相关推荐

  1. js Date 函数方法

    转载自   js Date 函数方法 var myDate = new Date();myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取 ...

  2. js Date对象总结

    Date在js中和Array类似,都是拥有自己的特殊方法的特殊对象. 由于平常用到Date着实不多,对它的了解颇浅.上周被问到怎么样获取某年某个月的天数,我当时想了一会儿,回答说有两种,一种自己写判断 ...

  3. JavaScript(JS) date.getDay()

    Date对象是JavaScript语言内建的数据类型.使用新的Date()创建日期对象.本文主要介绍JavaScript(JS) date.getDay() 方法. 原文地址:JavaScript(J ...

  4. JS - Date对象转时间戳

    JS Date对象转时间戳 关于Date对象转时间戳其实有蛮多例如dayjs这样的库能直接处理,不过前段时间在项目里只需要对两个日期时间进行比较,就没必要安装第三方库,简单记录一下我了解的几种方法: ...

  5. html 签到功能,从一个签到功能(日历)到 js Date 类型的全了解

    最近工做工做遇到一个签到功能,网上找了不少日历插件,发现都不是很适合,或者说不能很好的实现产品的需求,结果仍是本身撸了一个,撸的过程也是对js Date 类型从新学习了一遍,对 Date 类型的方法也 ...

  6. js Date 类型 的取值、计算、格式化 与 moment.js

    js Date 类型 的取值.计算.格式化 与 moment.js 前言 笔者工作多年,作为一个爱思考的程序员,一直在想一个问题:究竟怎样才可以让自己变的更强.. 对不起各位,说的太中二了,让我们重新 ...

  7. python 是什么类型的语言-python到底是什么类型的语言

    Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. 解释型语言:(推荐学习:Python视频教程) 程序不需要编译,程序在运行时才翻译成机器语言,每执 行一次都要翻译一次.因此效率比 ...

  8. 前端利用JS导出数据到Excel表 数字是文本类型 无法计算

    问题描述:前端利用JS导出数据到Excel表 数字是文本类型 无法进行公式计算:前端利用JS导出数据到Excel表 数字是文本类型 无法计算 解决办法:参考https://bbs.csdn.net/t ...

  9. python语音属于什么语言_python到底是什么类型的语言

    Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. 解释型语言:(推荐学习:Python视频教程) 程序不需要编译,程序在运行时才翻译成机器语言,每执 行一次都要翻译一次.因此效率比 ...

最新文章

  1. 使用阿里云服务器安装docker,并用nginx示例
  2. 千亿化妆品市场规模背后,女人正在失去不化妆的权利
  3. mysql 分组_mysql分组查询(总结)
  4. MSDN帮助文档 无法显示该网页 的问题解决方案(转)
  5. leetcode-551-Student Attendance Record I(判断是否出现连续几个相同字符)
  6. 蓝桥杯 子串分值 递推
  7. MYSQL教程之 concat
  8. SQL JOIN,你想知道的应该都有
  9. element 动态加载下拉框_动态增加select框(elementUI 框架)
  10. 百度回应“宕机”;微信 5 年内出 VR 版?腾讯破解谷歌漏洞 | 极客头条
  11. window10设置文件夹备注
  12. Trisk:在 Flink 实现以 task 为中心的流处理动态 Reconfiguration 的 Control Plane
  13. 【分论坛第一期大剧透】开源技术与新IT基础设施联袂共舞
  14. 如何用C语言编写字母游戏,怎么样用C语言编写一个小游戏?
  15. JavaScript使用正则表达式做表单验证
  16. ps制作2寸照片教程蓝底,ps怎么p二寸照片详细步骤
  17. 直播纠纷处理指引已出台,电商直播严监管来了!
  18. vue axios封装 类方法
  19. C# webBrowser打开网页出现脚本错误解决
  20. dojo query 实现Ajax,Dojo Query 详解

热门文章

  1. 关注地方门户网站盈利模式
  2. Flex开发中遇到未整理资源
  3. mysql标准化存储结构_Atitit.自定义存储引擎的接口设计 api 标准化 attilax 总结  mysql...
  4. ElasticJob corn定时表达式语法(亲测)
  5. pycharm同时注释多行代码快捷键
  6. Goland显示“Cannot resolve symbol XXX“ 进行更新IDE的索引库
  7. PHP的composer报错 failed loading cafile stream: `C:\Users\Administrator\Ap pData\Local\Temp\opeB1C9.t
  8. MySQL聚簇索引:叶子保存主键或unique字段+data 非聚簇保存索引字段
  9. Linux之CentOS防火墙及端口操作
  10. 学业水平考试b能上985吗_211 和985 的大学是不是要求学业水平考试全部是A