1.
var s = "test"; s.len = 4; var t = s.len;
t的值是undefined。s.len代码创建一个临时字符串对象,并给其len属性赋值为4,随即销毁这个对象。var t = s.len通过原始的(没有被修改过)字符串值创建一个新字符串对象,尝试读取其len属性,这个属性自然不存在,表达式求值结果为undefined。这段代码说明了在读取字符串、数字和布尔值的属性值的时候表现的像对象一样。但如果试图给其属性赋值,则会忽略这个操作:修改只是发生在临时对象身上,而这个临时对象并未继续保留下来。
存取字符串、数字或布尔值的属性时创建的临时对象称做包装对象。由于字符串、数字和布尔值的属性都是只读的,并且不能给它们定义新的属性。
var S = new String(s); var n = 1; var N = new Number(n); var b = true; var B = new Boolean(b);
== 等于运算符将原始值和其包装对象视为相等,但 === 全等运算符将它们视为不等。
2.
JavaScript中的原始值(undefined, null,布尔值,数字和字符串)与对象(包括数组和函数)有着本质的区别。原始值是不可更改的,任何方法都无法更改一个原始值。
原始值的比较是值的比较,只有在它们的值相等时它们才相等。
对象的比较均是引用的比较:当且仅当引用一个基对象时,它们才相等。
3.
+x //Number(x) ,x-0
x+"" //String(x)
!!x // Boolean(x)
Number类定义的toString()方法可以接收表示转换基数的可选参数,如果不指定参数,转换规则将是十进制。
toFixed()根据小数点后的指定位数将数字转换为字符串。
toPrecision() //根据指定的有效数字位数将数字转成字符串。如果有效数字的位数少于数字整数部分的位数,则转换成指数形式。
parseInt()和parseFloat()是全局函数,不从属于任何类的方法。
parseInt()只解析整数,parseFloat()则可以解析整数和浮点数。
如果字符串前缀是“0x”或者“0X”,parseInt()将其解释为16进制数。parseInt()和parseFloat()都会跳过任意数量的前导空格,尽可能解析更多数值字符,并忽略后面的内容。
如果第一个非空格字符是非法的数字直接量,将最终返回NaN。
parseInt()可以接收第二个可选参数,这个参数指定数字转换的基数。
4.
转换对象的函数是 toString和valueOf。
valueOf()//如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单地返回对象本身。 数组,函数和正则表达式简单地继承了这个默认的方法,调用这些类型的实例的valueOf方法只是简单返回对象本身。日期类定义的valueOf方法会返回它的一个内部表示:1970年1月1日以来的秒数
对象转换为数字的细节解释了为什么空数组会被转换为数字0以及具有单个元素的数组同样会转换成一个数字。数组继承了默认的valueOf方法,这个方法返回一个对象而不是一个原始值。因此,数组到数字的转换则调用了toString()方法。空数组转换为空字符串,空字符串转换为0
5.
+,==,!=和关系运算符是唯一执行这种特殊的字符串到原始值的转换方法。
6.
变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
JavaScript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。即JavaScript函数里声明的所有变量(但不涉及赋值)都被“提至”函数顶部。
“声明提前”这步是在JavaScript引擎的“预编译”时进行的,是在代码开始运行之前。
将函数内的声明“提前至”函数体顶部,同时变量初始化留在原来的位置。
7.
作用域链
如果将一个局部变量看做是自定义实现的对象的属性的话,
在JavaScript的最顶层代码中(也就是不包含在任何函数定义内的代码),作用域链由一个全局对象组成。
在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数和局部变量的对象,第二个是全局对象。
在一个嵌套的函数体内,作用域链上至少有三个对象