《Javascript高级程序设计》阅读笔记

随笔 2016-04-02

2016/3/28

1.当typeof操作符对象为null时,返回的是object,因为null表示空对象指针

2.alert()对未声明变量使用时,会产生错误,对未定义变量使用时,返回undefined;而typeof对于以上两种变量使用时,均返回undefined;

3.Nan与所有值不相等,即使Nan与Nan,即(Nan==Nan)返回false;

4.字符串一旦创建就无法改变,var lang =“java”;lang=lang+"script";这过程是先创建了一个10个长度的字符串,再销毁原来的两个字符串;

5.对于浮点数不要用相等来进行条件判断,如(0.1+0.2==0.3)是不成立的,因为存在舍入误差,实际值可能为0.300000009;

6.对字符串进行关系操作符运算的时候,比较首字母的字符编码值,大写字母小于小写字母。

2016/3/29

1.ECMAscript

ECMAscript可表示的数值范围存在Number.MIN_VALUE和Number.MAX_VALUE中, isFinite()函数可以判断一个数值是不是有穷的,

eg.

var result =Number.MAX_VALUE + Number.MAX_VALUE;

alert(isFinite(result));//false

2.Number()、parseInt()、ParseFloat()

  Number()针对所有数据类型,转换规则:

  • 对boolean类型,true和false转换为0和1;
  • 对null值,返回0;
  • 对undefined,返回NaN;
  • 对字符串,使用以下规则:
    • 若只包含数字,则转换成对应的十进制数值,并忽略前置的0,如“011"转换成11;
    • 若是空串,转换成0;
    • 不满足以上条件的,转换成NaN;
  • 针对对象(object)类型,调用ValueOf方法,然后采用以上的方法处理,碰到转换结果为NaN的,调用对象的toString方法,再按照之前的方法进行转换;

eg.

var num1 = Number("Hello world!");          //NaN

var num1 = Number("");                 //0

var num1 = Number("0011");               //11

var num1 = Number("true");                  //1

一元操作符+的操作与上述一致

parseInt()用于处理整数,碰到字符串时,

  • 对于空串,返回NaN;
  • 对于非空串,找到第一个非空字符,如果该字符是数字,则继续解析直到遇到非数字字符;若该字符不是数字返回NaN;
  • 在解析数字时,碰到0开头,当做8进制来解析,碰到0x开头的当做16进制解析,

eg.

var num1 = parseInt("red111");         //NaN

var num2 = Number("111red");          //111

var num3 = Number("22.5");             //22

var num4 = Number("70");               //70

var num5 = Number("070");             //56

var num6 = Number("0xf");             //15

   ECMAScript3 Javascript与ECMAscript5 Javascript在解析070时,前者会当作8进制来解析,后者会当作10进制来解析,为了消除这种情况,parseInt允许设置第二个参数来指定转换时使用的基数;

var num1=parseInt("0xAF",16);               //175
var num2=parseInt("AF",16);                 //175 
var num3=parseInt("AF")                     //NaN

   parseFloat()用于处理小数,碰到字符串时,与parseInt()相似,解析到一个无效 的浮点数数字符号为止,即碰到的第一个小数点是有效的,第二个无效;

    不同点是:1.parseFloat()始终忽略前导的0;

         2.碰到十六进制的时候会返回0;

eg.

var num1 = parseFloat("123abcsd");          //123
var num2 = parseFloat("0xA");                //0
var num3 = parseFloat("22.34.5");           //2.34
var num4 = parseFloat("070.5");             //70.5

3.String()与toString()

  toString适用于数值、布尔、字符串、对象,可设定参数为使用的进制基数:

eg.

var num1 = 10;
alert(num1.toString());        //"10"
alert(num1.toString(2));       //"1010"
alert(num1.toString(8));       //"12"
alert(num1.toString(10);       //"10"
alert(num1.toString(16));      //"a"

  String()适用所有类型的数据,且当数据可使用toString()时,使用对应方式;对于null返回null,对undefined返回undefined;

4.自增(++)自减(--)符号对于不同数据类型的处理:

  • 布尔值:true和false先转换成对应的0和1,然后进行增减操作;
  • 包含有效数字的字符串:先转换成数字,再转换成字符串;
  • 不包含有效数字的字符串:转换成NaN;
  • 对象:先调用valueOf()方法,对结果运用前述方式,若结果为NaN,则先调用toString()再按照前述方式;
var s1 = "2";
var s2 = "z";
var s3 = false;
var b = 1.1; 
var o = {
    valueOf:function(){
        return -1;
    }
};
s1++;                              //3
s2++;                              //NaN
s3++;                              //1 
b--;                               //0.100000000000009(浮点数考虑舍入误差)
o--;                               //-2

5.关系操作符中的一些注意点:

  1.与NaN有关的比较操作都返回false;

  2.数字字符串比较操作时,若两边都是字符串形式,则按照字符串编码来比较;若有其中一边为数字形式时,自动把另外一边转换成数字形式进行比较;若另一边无法转换为数字,则转换成NaN,即返回false;

var result1 = "23" < "3";                          //true     字符串比较 
var result2 = "23" <  3;                           //false    数值比较 
var result3 = "a"<3;                               //false  左边转变为NaN
var result4 = NaN < 3;                             //false 
var result5 =NaN >=3;                              //false

6. 相等(==)与不相等(!=)

操作符会在比较之前进行相应的强制转换,规则如下:

  • 如果有一个操作数为boolean,则在比较前先将其转换为数值--false为0,true为1;
  • 一个操作数为数字,另一个操作数为字符串时。先把数字转换为字符串;
  • null与undefined相等  
  • 一个操作数为对象,另一个操作数不是时,对对象类型先调用valueOf()方法;再按照上述规则进行比较
  • 当一个操作数为NaN时,相等操作符返回false,不等操作符true;
  • 当两个操作数均为NaN的时候,相等操作也返回false,因为false不等于false;
  • 当两个操作数都是对象时,如果他们是同一个对象,相等操作符返回true,不等操作符返回false;
null == undefined               //true
"NaN" == NaN                     //false
NaN == NaN                       //false
NaN != NaN                       //true
false == 0                       //true
null == 0                        //false
undefined == 0                   //false

在全等(===)与不全等(!==)比较中

  undefined与null不相等

2016/3/30

1.关于ECMAScript参数

  与C语言不同,ECMAScrip函数的参数,不介意参数的类型和个数。因为参数是用一个数组来表示的,函数只接受这个数组中具体包含的内容。实际上,可以在函数内部通过直接访问这个数组来获取参数:

function add(a,b)
{ 
    return a+b;
} 
function add()
{ 
    return arguments[0]+arguments[1];  
} //两个函数效果等价

同时,可以通过arguments.length判断传入的参数个数;

2.关于ECMAScript函数重载

由于之前提到的参数用数组表示,没有函数签名,因此ECMAScript函数没有函数重载,当定义两个同名函数时,以后定义的函数为准;

3.变量的基本类型

ECMAScript的变量数据类型有的值两种:基本类型值和引用类型的值

  (1)基本数据类型包括undefined、null、boolean、number、string;这几类数据都是按值访问的,可以操作保存在变量中的值;

    引用类型是保存到在内存中的对象,在js中不允许直接访问内存的位置,实际操作的是对象的引用而不是对象,所以是按引用访问的;

  (2)引用类型的值可以进行添加或者删除属性和方法,如:

var person = new Object();
person.name = "mike";
alert(person.name);//mike

     基本类型不支持此操作;

  (3)在复制变量值时:

    基本类型会创建一个副本,再进行赋值,创建的新值与原先的变量完全独立;

    引用类型会创建一个副本指针,指向与原指针完全相同的对象;

//基本类的值
var num1=5; var num2=num1;
num2++;
alert(num1);//5
alert(num2);//6
//引用类型的值

var obj1=new Object(); var obj2=new Object();

obj1.name-"Mike";

alert(obj2.name);//Mike

  (4)在传递参数时:

    在ECMAscript中所有的函数都是按值传递的。

    在传递基本类型参数时,传递的值先赋值给一个局部变量,即函数内部的参数;在传递引用类型的值时,会把这个值在内存中的地址传递给一个局部变量,因此,这个局部变量的变化会反映在函数的外部

function addTen(num){
    num+=10;
   return num;        
}
var count = 20;

var result = addTen(count);

alert(count);//20

alert(result);//30

    在这个例子中,num与count仅仅是拥有相同的值,在函数执行过程中,count并不会发生变化,因此输出的count仍然是20;如果是按引用传递的话,那么变量count的值也会变成30;在基本类型的值里面,这一点比较容易区分,但是在引用类型的值中,很容易被混淆--这里抛出一个问题:如果在局部作用域中修改的对象可以在全局域中反映出来,就说明参数是按引用传递的吗?答案是否定的。

function setName(obj){
  obj.name="Mike";  
}
var person = new Object();
setName(person);
alert("person,name"); //Mike

  在上面的例子中,把person传递到函数中,复制给了obj,在这个函数内部,obj和person引用的是同一个对象,也就是说,这个变量是按值传递的,这个例子看起来有点像是按照引用传递的,因为它完全切合上面提到的问题,那接下来再举出一个反例:

function(){
  obj.name = "Mike";
  obj = new Object();
  obj.name ="Greg";    
}
var person = new Object();
setName(person);
alert(person,name);//"Mike"

  这段代码与上一段的区别仅仅在于增加了两行,为obj重新定义了一个对象,并且为新的对象定义了一个不同的name属性。假设person是按引用传递的话,那么person会自动被修改为指向name值为Greg的新对象,然后从结果我们可以看到,person任然是指向name值为Mike的对象的,这说明即使在函数内部修改参数的值,但原始的引用仍然未改变。

2016/3/31

1.检测类型

  检测基本比变量的类型可以使用typeof操作符,但是在检测引用类的值时,要使用instanceof操作符。这个操作符可以直接检测对象是什么类型的引用对象

alert(person instanceof Object);   //判断对象是否是boject
alert(person instanceof Array);   //判断对象是否是Array
alert(person instanceof RegEXp);   //判断对象是否是RegExp

2.执行环境和作作用域

  执行环境:变量或者函数的访问权限,每个执行环境都关联一个变量对象,在Web浏览器中,全局执行环境是window对象。

  每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就被推入一个环境栈中;


本文由 malinlin 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

如果对您有用,您的支持将鼓励我继续创作!