前端学习 第一弹:  JavaScript关于 对象和原始值以及+ 的知识点

关于原始值的问题

在 JavaScript 中,一共有两种类型的值:

  • 原始值(primitives)

    1. undefined

    2. null

    3. boolean

    4. number

    5. string

  • 对象值(objects)。

除了原始值外,其他的所有值都是对象类型的值,包括数组(array)和函数(function)。

 

 

JavaScript 引擎内部的抽象操作 ToPrimitive() 有着这样的签名:

ToPrimitive(inputPreferredType?)

可选参数 PreferredType 可以是 Number 或者 String。 它只代表了一个转换的偏好,转换结果不一定必须是这个参数所指的类型(汗),但转换结果一定是一个原始值。

其步骤又如下几步:

1.if input是原始值 return input

2.if input是对象 x=input.valueOf(); if x是原始值 return x;

3.y=x.toString();

  if y是原始值 return y

  else 抛出 TypeError 异常

通过 ToNumber() 将值转换为数字

下面的表格解释了 ToNumber() 是如何将原始值转换成数字的 (§9.3)。

参数结果
undefined NaN
null +0
boolean true被转换为1,false转换为+0
number 无需转换
string 由字符串解析为数字。例如,"324"被转换为324

如果输入的值是一个对象,则会首先会调用 ToPrimitive(obj, Number) 将该对象转换为原始值, 然后在调用 ToNumber() 将这个原始值转换为数字。

 

通过ToString()将值转换为字符串

下面的表格解释了 ToString() 是如何将原始值转换成字符串的(§9.8)。

参数结果
undefined "undefined"
null "null"
boolean "true" 或者 "false"
number 数字作为字符串。比如,"1.765"
string 无需转换

如果输入的值是一个对象,则会首先会调用 ToPrimitive(obj, String) 将该对象转换为原始值, 然后再调用 ToString() 将这个原始值转换为字符串。

 

那么为什么 (1+{})[4]='j' ?往下看

 

二元加法运算

在js中   value1 + value2 又如下的计算步骤

  1. 将两个操作数转换为原始值 (以下是数学表示法的伪代码,不是可以运行的 JavaScript 代码):

    javascript prim1 := ToPrimitive(value1) prim2 := ToPrimitive(value2)

    PreferredType 被省略,因此 Date 类型的值采用 String,其他类型的值采用 Number

  2. 如果 prim1 或者 prim2 中的任意一个为字符串,则将另外一个也转换成字符串,然后返回两个字符串连接操作后的结果。

  3. 否则,将 prim1 和 prim2 都转换为数字类型,返回他们的和。

 

所以根据以上内容有一下结论:

[]+{}='[object Object]'

1+{}='1[object Object]'(1+{})[4]='j'

arr=[];  arr.valueOf()===arr = true;

1+{valueOf : function(){ return 2;}} = 3

'abc' + {toString : function(){ return 'def'}} = 'abcdef'

[]+[]=''

[1,2]+[3,4]='1,23,4'

一元运算符 +

当我们按照上面的二元+来计算到 {}+{}会惊奇的发现结果等于 NaN   !

其实这里使用的是一元运算 +value  将value转化为数字 和Number()效果一样。

所以

+"213"=213

+[]=0

{}+{}=NaN;

({}+{})='[object Object][object Object]'

 

但是不同的引擎对于{}+[]结果并不相同

chrome&firefox :  {}+[]=0

Node.js:      {}+[]=''

 

所以我们来看为什么++[[]][+[]]+[+[]] = '10'

++[[]][+[]]+[+[]]

1step.  ++[[]][0]+[0]  (这里[[]][0]是[[]]数组的第一个元素也就是[] )

2step.  ++[]+'0'   (++[]等效于+([]+1)=+(''+1)=+('1')=1)

3step.  1+'0'       ==='10'

 

 

补充js中连接对象和数组的方法

[1, 2].concat([3, 4])
[1, 2, 3, 4]
> var o1 = {eeny:1, meeny:2};
> var o2 = {miny:3, moe: 4};
> _.extend(o1, o2)
{eeny: 1, meeny: 2, miny: 3, moe: 4}

不过需要注意的是concat中[1,2]并未改变,而.extend方法中o1={eeny :1, meeny:2, miny:3, moe:4} o2不变