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

Javascript引擎内部的三种抽象操作 #9

Open
xx19941215 opened this issue Jul 20, 2017 · 0 comments
Open

Javascript引擎内部的三种抽象操作 #9

xx19941215 opened this issue Jul 20, 2017 · 0 comments

Comments

@xx19941215
Copy link
Owner

很久之前我在知乎上问过一道很无聊的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()是如何将原始值转换成数字的

ToNumber()转换规则
如果输入的值是一个对象,则会首先会调用ToPrimitive(obj, Number)将该对象转换为原始值,然后在调用ToNumber()将这个原始值转换为数字.转型函数Number()会根据此规则执行

3.通过ToString()将值转换为字符串
下面的表格解释了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得到的结果:
相关总结

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

No branches or pull requests

1 participant