首页 > 代码库 > 《javascript高级程序设计(第二版)》学习(2)
《javascript高级程序设计(第二版)》学习(2)
数值转换:有3个函数可以把非数值转为数值,Number(),parseInt(),parseFloat()。
对于Number() 如果是
- 布尔型,true为1,false为0;
- Null为0;
- undefined为NaN;
- 而字符串情况就比较多:如果有包含数字(不论是整数还是浮点数,抑或是有效的十六进制数如0xf)都会转变为数字,如“11a1”只输出11,“0xa11”则会按照16进制输出。字符串如果是空的,则为0;上述情况以外的字符,则为NaN;
- 如果是对象,会先调用对象的valueOf()方法,然后依照前面规则;如果是NaN,则调用toString();再次按照前面的规则来转换;
parseInt()用的比较多,会忽略字符串前面的空格,直到找到第一个非空格字符,如果找到的这个不是数字字符或者负号,就会返回NaN。因此“22.2”“22blue”这两个输出的都是22,前者因为“.”不符合,后者因为blue不符合。在对进制的转换存在分歧,因此可以指定第二个参数,来指定他的基数。
例如parseInt("10", 10) ,parseInt("10", 8)。当指定了16进制的时候,字符串可以不带前面的0x。
parseFloat()与上面类似,不同的是,它可以解析浮点数,但出现第二个“.”的时候,就停止转换。另外他只能做十进制的,没有第二个参数,所以会忽略十六进制的“0x”前面的0;
toString()方法一般不会传递参数,某些情况也可以传递一个参数,作为输出数值的基数。
var num=10;alert(num.toString(2)) //输出1010
要把某个数值转变为字符串,可以使用“+”号操作符,把它与一个字符串("")加在一起,输出的结果就是字符串
在ECMAScript中,Object类型是所有它的实例的基础。Object具有下列的属性和方法:(ECMA-262)
- Constructor:保存用于创建当前对象的函数。
- hasOwnProperty(propertyName):用于检查给定的属性是否在当前对象的实例中是否存在,其中propertyName必须以字符串形式指定;
- isPrototypeOf(object):用于检查传入的对象是否是另外一个对象的原型。
- propertyIsEnumerable(propertyName):用于检查给定的属性是否可以用for-in来枚举;
- toString():返回对象的字符串表示;
- valueOf():返回对象的字符串,数值或者布尔值表示。
switch语句中可以使用任何数据类型,甚至是对象都可以。其次,每个case值不一定是常量,甚至可以是变量,甚至是表达式。
switch("hello world"){ case"hello"+"world": alert("greeting was found"); break; case"goodbye": alert("closing was found"); break; default: alert("Unexpected message was found");}
参数
在ECMAScirpt中的参数内部是用一个数组来表示的,函数接收到的始终是这个数组,而不关系数组中包含了那些参数。实际上,在函数体内,可以通过arguments对象访问这个参数数组,从而获取传递给函数的每一个参数。arguments对象只是与数组类似,可以使用索引来访问其中的参数。
//下面这个函数没有定义参数,但是这个方法依然是可以的function sayHi(){ alert("hello"+arguments[0]+arguments[1]);}sayHi("mike", "goodmorning"); //执行结果 hello mike goodmorning
在JavaScript的严格模式中,对于arguments对象做了限制,如下面这种赋值方法就会变得无效
function doAdd(num1, num2){ arguments[1]=10; alert(arguments[0]+num2); //这里num2已经被赋值为10了}
每次执行doAdd()函数都会重写第二个参数,将第二个参数的值变为10.因为arguments对象中的值会自动反映到对应的命名参数,所以修改arguments[1]也就修改了num2。不过读取这两个值并非是访问相同的内存空间:他们的内存空间是独立的,但值会同步,这种影响是单向的,修改num2不会改变arguments[1]的值。另外,如果只传入了一个参数,那么arguments[1]设置的值不会反映到命名参数(就是括号中的参数)中去。因为arguments对象的长度是由传入的参数个数来决定的,而不是定义函数的命名参数个数决定的。另外,没有传递值得命名参数将自动被赋予undefined。
ECMAScript变量可能包含两种不同的数据类型:基本数据类型(简单的数据段)和引用类型值(由多个值构成的对象)
5中基本数据类型(undefined,null,Boolean,number,string)是按值访问的,因为可以操作保存在变量中的实际的值。引用类型的值是保存在内存中的对象,和其他语言不同,JavaScript不允许直接访问内存中的位置,不能直接操作对象的内存空间。在操作对象时,实际上操作对象的引用,而不是实际的对象。因而,引用类型的值是按照引用访问的。
复制变量的值:在从一个变量向另外一个变量复制基本类型值和引用类型时,也存在差异。
/*下面的例子中,num1中保存的是5,用num1去初始化num2时,num2也保存了5,但这两个5是完全独立的,不受彼此的影响*/var num1=5;var num2=num1;/*引用类型的值就不一样,下面例子中变量obj1保存了一个对象的新实例。然后,赋予到obj2中,这时连个都指向了同一个对象。当obj1增加了name后,obj2也拥有了这个属性*/var obj1=new Object();var obj2=obj1;obj1.name="mike";alert(obj2.name); //输出Mike;
传递参数
ECMAScript中所有函数的参数都是按照值传递的。
/*基本数据类型的参数传递是按照值来传递的,函数内的修改无法传递给外部*/function addTen(num){ num += 10; return num;}var count=20;var result=addTen(count);alert(count); //20 没有变化alert(result); //30/*引用类型的值的参数传递依然是值传递,如果是引用传递,那么再第二次修改的时候,就应该得到“jim”。
但是当访问name属性的时候,得到的依然是mike。说明即使再函数内部修改了参数的值,但原始的引用仍
然没有变化。实际上函数内部重写obj时,得到的是局部对象,在执行完毕后就被垃圾回收机制回收了。*/function setName(obj){ obj.name="mike"; obj=new Object(); obj.name="jim"; alert("local: "+obj.name); //局部对象时jim}function setName(obj){ obj.name="mike"; //obj={}; obj.name="jim"; //这个得到的结果就是jim,覆盖了之前的赋值}var person=new Object();setName(person);alert(person.name); //mike
《javascript高级程序设计(第二版)》学习(2)