json tostringfiy_JS学习笔记 : 类型转换之「抽象值操作」

这要是没搞懂你好意思说学过JS?

这怕是JavaScript中最坑、最有毒的一个部分了。

将值从一种类型转换成另一种类型叫做类型转换。例如:

var a = 1;

var b = String(a); // "1" 显式转换var c = "" + a; // "1" 隐式转换

在JavaScript中,我们把上面列举的两类转换都称为 强制类型转换 ,按照显式和隐式的区别我们可以将强制类型转换分为 显式强制类型转换 和 隐式强制类型转换 。

当然要注意,这里的显式和隐式都是相对的。假如你对JavaScript运行中的所有将要执行的类型转换都牢记于心,那当然可以把他们全部称为显式强制类型转换。本文主要参考《你不知道的JavaScript中卷》,因此参照书中的标准来界定显式和隐式。

JavaScript中的强制类型转换总是返回标量基本类型值,例如字符串、数字和布尔值,不会返回对象和函数。

这篇文章会学习抽象值操作。

ToString

基本类型的字符串化规则为:null转换为"null"

undefined转换为"undefined"

true转换为true

数字的字符串化则遵循通用规则,对于极小和极大的数使用指数形式

对于对象来说,字符串化的时候会调用对象的toString()方法,并使用其返回值。如果没有自行定义的话,toString()方法会默认返回内部属性[[Class]]的值。例如以下的例子:

"" + {}; // "[object Object]"

"" + [1,2,3]; // "1,2,3""" + {toString: function(){return "1"}}; // "1"

toString() 可以被显式调用,或在需要字符串化的时候自动调用。

JSON 字符串化

JSON应该是我们在JS中最常用的序列化和反序列化工具之一了。JSON.stringify()在将对象序列化为字符串的时候也用到了ToString。但是需要注意,JSON字符串化并非严格意义上的强制类型转换。

对于大多数基本类型值来说,JSON字符串化的结果和toString()是差不多的,只不过序列化的结果总是字符串:

JSON.stringify(1); // "1"JSON.stringify("1"); // ""1"" (带有双引号的字符串)JSON.stringify(null); // "null"JSON.stringify(true); // "true"

有些值JSON是无法处理的,例如:undefined、function、symbol 和包含循环引用(对象之间相互引用)的对象。我们把这些它们称作 不安全的JSON值 。

相对的,所有 安全的JSON值(JSON-safe) 都可以使用JSON.stringify()字符串化。

JSON.stringify() 在对象中遇到 undefined、 function 和 symbol的时候会自动忽略他们,在数组中这回返回null(为的是保证数据的下标不变),在遇到循环引用的对象时会报错。例如:

JSON.stringify(undefined); // undefinedJSON.stringify(function(){}); // undefined

JSON.stringfiy(

[1, undefined, function(){}, 4]

); // "[1,null,null,4]"JSON.stringify(

{a: 1, b: function(){}, c: undefined }

); // "{"a":1}"JSON.stringify(

{toString: function(){return "1"}}

); // "{}"

var a = {};

var b = {a: a};

a.b = b;

JSON.stringify(a); // Uncaught TypeError: Converting circular structure to JSON

如果对象中定义了toJSON()方法,JSON字符串化的时候会首先调用该方法,然后用它的返回值来进行序列化。如果你对某些非法JSON值定义了toJSON()方法,并返回一个安全的JSON值,那么这个值就能被字符串化了。 注意,对象是不自带toJSON()方法的,需要你主动定义它。 例如:

var a = {};

var b = {a: a};

a.b = b;

b.toJSON = function(){

return {};

};

JSON.stringify(a); // "{"b":{}}"

var foo = function(){}

foo.toJSON = function(){return 123}

JSON.stringify(foo); // "123"

var bar = {

a: undefined,

toJSON: function (){ return {a: null} }

}

JSON.stringify(bar); // "{"a":null}"

toJSON()返回的并不一定是JSON字符串化后的值(这样其实会对字符串再做一次字符串化),而应当是一个适当的值,可以是任何类型,然后再由JSON.stringify()对其字符串化。

ToNumber

ToNumber相比ToString来说就简单很多。

将基本数据类型转换为数字的规则为:

- true转换为1

- false转换为0

- undefined转换为NaN

- null转换为0

- 对字符串的转换遵循通用规则,处理失败时返回NaN,对以0开头的十六进制数按十进制处理而非十六进制。

对于对象来说,它们会先被转换成相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其转换成数字。

对象转换成基本类型值的规则为:首先检查是否有valueOf()方法,如果有并且返回基本类型值,就使用改值进行转换。如果没有则使用toString()方法的返回值(如果存在)来进行强制类型转换。如果valueOf()和toString()都不反悔基本类型值,则会产生TypeError错误。

几个例子:

var a = {valueOf: function(){return "1"}};

var b = {toString: function(){return "2"}}

Number(a); // 1Number(b); // 2

var c = [1,2,3];

Number(c); // NaNc.valueOf = function(){

return 1;

}

Number(c); // 1

var d = [];

Number(d); // 0d.toString = function(){

return 1;

}

Number(d); // 1

var e = [1,2,3];

e.toString = function(){

return this.join("") // 123}

Number(e) //123

ToBoolean

boolean的两个字true和false分别代表着 真 和 假 。在JavaScript中,数字1和0与true和false并不等价。

对于基本类型值来说,JavaScript中的值可以分为两类:

- 可以被强制类型转换成false的值

- 其他(可以被强制类型转换成true)的值

以下的值为 假值 :

- undefined

- null

- false

- +0、-0和NaN

- ""

除了假值表以外的所有值都可以理解为 真值 。

一般来说,所有的对象都是真值,但是有一些特殊情况,我们可以把他们叫做 假值对象 。

先来说几个例子——

var a = new Boolean(false);

var b = new Number(0);

var c = new String("");

var d = new Boolean(0);

var foo = Boolean(a && b && c &&d);

foo; // true

foo为true,说明a、b、c、d都为true。

这些封装了假值的对象都并非假值。

我们来看看真正的假值对象——他们是来自浏览器在某些特定条件下创造的对象,例如document.all:

document.all; // 返回一个 HTMLAllCollection 对象!!document.all; // false

这是一个类数组对象,由DOM提供(而非JavaScript引擎)提供给JavaScript程序使用。它以前曾是一个真正意义上的对象,布尔强制类型转换的结果为true,但现在它是一个假值对象——并且这已经死一个被废止的方法了。

由于很多JavaScript程序依赖document.all来判断是否是旧版浏览器,因此一直没有把它去掉。

再说一说几个真值的情况——虽然刚才说过了假值表以外的都是真值,但是你还可能会遇到一些比较刁钻的状况:

var a = Boolean("false");

a; // true

var b = Boolean("0");

b; // true

var c = Boolean("\"\"");

c; // true

对于字符串来说,除了""以外都是真值。同时,对于[]、{}、function(){}这一类的对象都是真值。

参考《你不知道的JavaScript中卷》第一部分第四章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cont char *p 和 char* const p 区别及记忆方法

/* cont char *p 和 char* const p 区别及记忆方法 const char *p "hello"; 和 char const *p "hello"; 等价 保护的是内容(即这段buffer只读, 记忆:const 在*p前, *p是取内容,保护内容&am…

eclipse和Tomcat绑定

在file下new一个Dynamic Web Project 取好名字,点击next 或者finish都可以,完成创建 点击window,选择preferences 在搜索框里输入server,然后点击Runtime Environments 点击add 我的版本是7,选择7,大家是那个版本就选择…

OD里alt+F9和Ctrl+F9和shift+F9的区别

ShiftF9 - 与F9相同,但是如果被调试程序发生异常而中止,调试器会首先尝试执行被调试程序指定的异常处理(请参考忽略Kernel32中的内存非法访问)。 CtrlF9 - 执行直到返回,跟踪程序直到遇到返回,在此期间不进…

kafka数据不丢失不重复_超高速底层系统数据复制,安全精准不丢失

大家好,我是IT数码手机控,一名究极数码爱好者,喜欢最潮最酷的数码好物,追求科技美学,数码圈里最懂艺术,艺术圈里最会修电脑的女汉纸~而今天就给大家介绍佑华硬盘数据拷贝机。— ❶ —外观质感拿到佑华 PRO-…

程序之美

程序的美要从两个方面进行品味,一是程序整体的架构之美;一是程序的代码实现之美。编码之美:编程就是为解决一个计算机能够解决的问题写出具体的程序实现。开始,人们总是从发现代码之美开始的,从把代码一股脑的写在main…

[沫忘录]mysql基础(函数及约束)

[沫忘录]mysql基础(函数及约束) mysql内置函数 字符串函数 #字符串拼接 CONCAT(S1, S2...S3)#全转小写 LOWER(str)#全转大写 UPPER(str)#用pad将str左填充至n长 LPAD(str, n, pad)#数值也可当做字符串#用pad将str右填充至n长 RPAD(str, n, pad)#去掉首尾的空格 TRIM(str)#截…

如何在Visual Studio项目中正确添加汇编代码 .

引用注明>> 【作者:张佩】【镜像:www.yiiyee.cn/blog】 1. 问题描述 在以往的编程经历中,本人最常使用的汇编代码是__asm {int 3}。它可以在我的代码中插入一个软件断点。如果没有一个连接到当前程序的调试器,则程序将…

eclipse代码发布到服务器(Tomcat)出现乱码现象解决方法

我们只需写两行代码就可以解决问题了 //设置response查询的码表 response.setCharacterEncoding(“UTF-8”); //通过一个头Content - Type 告知客户端使用何种码表 response.setHeader(“Content-Type”, “text/html;charsetUTF-8”); response.getWriter().write(“…

多叉树的前序遍历_二叉树的非递归遍历的思考

封面图来自wikipedia1 简介二叉树的深度优先遍历(前序遍历、中序遍历、后序遍历)是一个比较基本的操作。如果使用递归的做法,很容易写出相应的程序;而如果使用非递归的做法,虽然也能写出相应的代码,但是由于…

delphi中Label中文显示不全的问题解决办法

有时候把Label的AutoSize属性设置为True,当窗体显示的时候,Label中的内容可能会显示不完全,只能把AutoSize设置为False, 把Label调整成能显示出内容的大小。还有一种更简单的解决方法。把Form的Font属性进行如下设置:字…

vs+vm双机调试

基础: VS2017安装成功 wdk10 注意事项: 关闭 、主机 客户机 防火墙 、 互相ping都能ping通。 一、具体操作步骤 工具安装就不说了,不会的百度一下。只说一下一些关键的地方。 1、安装好虚拟机后,给虚拟机增加一个串口设备。具体…

为什么要返回softmax_为什么softmax搭配cross entropy是解决分类问题的通用方案?

众所周知,softmaxcross entropy是在线性模型、神经网络等模型中解决分类问题的通用方案,但是为什么选择这种方案呢?它相对于其他方案有什么优势?笔者一直也困惑不解,最近浏览了一些资料,有一些小小心得&…

servlet下载文件(注意文件名字必须是英文)

直接将代码放在servlet下,把文件名字换成自己要下载的就行 文件要放在WEGCONTEN下 //获得下载文件的名称String filename request.getParameter("filename");//要下载的这个文件的类型 -----客户端根据mime类型区分别response.setContentType(this.getS…

2010.07.13_19:30

又是地铁中,音乐在响,离目的地一半,又一天上班结束。转载于:https://www.cnblogs.com/sunxi2003/archive/2010/07/13/1776724.html

焊接空间臂_焊接烟尘净化器设备哪种好

焊接烟尘净化器设备采用滤筒除尘器,焊接烟尘净化器用于焊接、切割、打磨等工序中产生烟尘和粉尘的净化以及对稀有金属、贵重物料的回收等,可净化大量悬浮在空气中对人体有害的细小金属颗粒。具有净化效率高、噪声低、使用灵活、占地面积小等特点。 适用于…

关于Tomcat文件下载中文名乱码现象

//获得下载文件的名称 String filename request.getParameter(“filename”); //解决获得中文参数的乱码 filename new String(filename.getBytes(“ISO8859-1”),“UTF-8”); //获得请求头的User-Agent String agent request.getHeader(“User-Agent”); //根据不同的浏览器…

【摘录】C语言中利用 strtok函数进行字符串分割

C语言不像Java,Php之类的高级语言,对象中直接封装了字符串的处理函数。C语言中进行普通的字符串处理也经常会让我们焦头烂额……不过好在C语言 中还是提供了像strtok这样功能强大的字符串处理函数,可以帮我们实现部分需要的功能。下面我们介绍一下strtok…

x86汇编指令大全

X86和X87汇编指令大全(有注释) ---------- 一、数据传输指令 ---------------------------------------------------- 它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据. 1. 通用数据传送指令. MOV 传送字或字节. MOVSX …

woe分析_Python数据分析—apply函数

在对海量数据进行分析的过程中,我们可能要把文本型的数据处理成数值型的数据,方便放到模型中进行使用。也可能需要把数值型的数据分段进行处理,比如变量的woe化。而这些操作都可以借助python中的apply函数进行处理。今天介绍数据分析的第四课…

树莓派3b安装ubuntu mate(在有显示器前提下看)

树莓派安装: 准备材料 tf卡(建议16G)数据线树莓派win32烧录软件 ,百度云链接:链接:https://pan.baidu.com/s/16Dq2XrqeJScUO_DxHRIz_g 提取码:kfkbubtuntu mate系统(建议不要下ubu…