Javascript引擎内部的三种抽象操作
来源:互联网 发布:电气控制柜的设计软件 编辑:程序博客网 时间:2024/06/06 08:59
很久之前我在知乎上问过一道很无聊的Js题目,链接在这里JS中{}+[]和[]+{}的返回值情况是怎样的?,这篇文章要说的和这个题目有一些关系。下面介绍一下Js引擎内部的三种抽象操作。
1.通过ToPrimitive()将值转换为原始值。
JavaScript引擎内部的抽象操作ToPrimitive()有着这样的签名:
ToPrimitive(input, PreferredType)
可选参数PreferredType可以是Number或者String,它只代表了一个转换的偏好,转换结果不一定必须是这个参数所指的类型,但转换结果一定是一个原始值.如果PreferredType被标志为Number,则会进行下面的操作来转换输入的值:
①如果输入的值已经是个原始值,则直接返回它.否则,如果输入的值是一个对象.则调用该对象的valueOf()方法.如果valueOf()方法的返回值是一个原始值,则返回这个原始值.否则,调用这个对象的toString()方法.如果toString()方法的返回值是一个原始值,则返回这个原始值.否则,抛出TypeError异常.
②如果PreferredType被标志为String,则转换操作的第二步和第三步的顺序会调换.如果没有PreferredType这个参数,则PreferredType的值会按照这样的规则来自动设置:Date类型的对象会被设置为String,其它类型的值会被设置为Number.
2.通过ToNumber()将值转换为数字
下面的表格解释了ToNumber()是如何将原始值转换成数字的
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用ToNumber()将这个原始值转换为数字.转型函数Number()会根据此规则执行
3.通过ToString()将值转换为字符串
下面的表格解释了ToString()是如何将原始值转换成字符串
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, String)将该对象转换为原始值,然后再调用ToString()将这个原始值转换为字符串.转型函数String()会根据该规则执行
理解了Javascript引擎内部的三种抽象操作之后可以看下面的例子:
这里的转型函数Number会根据2的规定来执行类型转换,由于重写了对象的valueOf和toString函数(之前toString会返回”[object Object]”,valueOf会返回该对象),所以Number()根据规则首先调用对象的valueOf方法,没有获得原始值,继续调用toString方法,任然没有获得原始值,这时就会抛出TypeError。
再来看一个例子:即{}+[]和[]+{}的返回值是怎么样?
对于{}+[] 我们将{}理解为一个空的代码块,所以问题就变成了 +[] 的结果,这里的加号并不是代表加法的二元运算符,而是一个一元运算符,作用是将它后面的操作数转换成数字,和Number()函数作用完全一样,即求Number([])的结果是多少?[]继承自Array,Array对象的的valueOf方法直接返回该数组并不是原始值,继续调用toString方法,得到”“即一个空的字符串。那么Number(“”)的结果就是0,所以{}+[]的结果就是0。而[]+{}的结果呢?你可以参考《Javascript高级程序设计》的3.5.5加性操作符一章和本文的相关说明获得答案是”[object Object]”。
文章的最后总结一些类型分别调用valueOf、toString和toLocaleString得到的结果:
本文同步发布在
知乎 Javascript引擎内部的三种抽象操作
简书 Javascript引擎内部的三种抽象操作
- Javascript引擎内部的三种抽象操作
- 【JS】JavaScript引擎的内部运行机制
- 【JS】JavaScript引擎的内部运行机制
- 【JS】JavaScript引擎的内部运行机制
- 探索推荐引擎内部的秘密(三)
- 实现抽象类内部的抽象方法
- 改变javascript函数内部this指针指向的三种方法
- 改变javascript函数内部this指针指向的三种方法
- 推荐引擎内部的秘密
- 推荐引擎内部的故事
- JavaScript 工作机制:V8 引擎内部机制及如何编写优化代码的 5 个诀窍
- 初学JavaScript的操作DOM节点(三)
- 工作流引擎的三种定位
- 工作流引擎的三种定位
- 工作流引擎的三种定位
- 工作流引擎的三种定位
- 工作流引擎的三种定位
- 工作流引擎的三种定位
- Android应用程序访问linux驱动第三步:实现并向系统注册Service
- 微信小程序推荐大全之101~200个
- CentOS 7 安装Kubernetes(1)--手动部署节点
- arm汇编程序调用C函数之参数传递
- 一分钟了解“Matlab的squeeze函数”
- Javascript引擎内部的三种抽象操作
- 正向代理与反向代理、负载均衡
- 解决浏览器登陆GitHub官网提示404的问题
- 两款Docker管理UI:DockerUI & Shipyard
- C# this.Invoke()的作用与用法
- Java多线程——获取多个线程任务执行完的时间
- Nginx安装与负载均衡配置
- 最大和
- js判断全选与全不选以及,js全不选时全选按钮会被勾掉