啃一啃犀牛书--表达式和运算符(1)

啃一啃犀牛书–表达式和运算符(1)

对象和数组的初始化表达式

这里面有一个地方需要注意:

1
2
var a = [1,2,3,];  //[1,2,3]
var b = [1,2,3,,5]; //[1,2,3,undefined,5]

列表逗号之间的元素省略,会填充undefined,但是末尾处不会。从这引申出一个知识点:我们一般定义数组是使用数组直接量的方法,但是我们也知道定义数组还可以使用构造函数的方法

1
var a = new Array(1,2,3);

这里面如果我们如下定义:

1
2
var a = new Array(1,2,3,);    //等同于a = [1,2,3,]
var b = new Array(1,2,,4); //会报错。Uncaught SyntaxError: Unexpected token ,

而且一般情况我们的数组定义还是尽量使用数组直接量的方式,这种方式从效率上来讲要比构造函数快。

属性访问表达式

属性访问表达式有两种,一种是”.”操作符,另外一种就是中括号的形式。

不管使用哪种方式的属性访问表达式,在”.”和”[“之前的表达式总是会首先计算。如果计算结果是null或者undefined,表达式都会抛出一个类型错误异常,
因为这两个值都不能包含任意属性。如果运算结果不是对象(或数组),js会将其转换为对象。

显然.identifier的写法更加简单,但需要注意的是,这种方式只适用于要访问的属性名称是合法的标识符,并且需要知道要访问的属性的名字。
如果属性名称是一个保留字或者包含空格和标点符号,或是一个数组(对于数组来说),则必须适用方括号的写法。当属性名是通过运算得出的值而不是固定的值的时候,
这时必须适用方括号写法。

1
2
3
var a = 'onload';
window.onload = function(){};
window[a] = function(){}
运算tips

递增++,相信我们都用过不少,比如for循环里面的i++,抑或是滚动加载时候的page++,但是i++和++i,一样么?

1
2
3
4
5
var i = 1,j = ++i;
console.log(i,j); //2,2

var i = 1,j = i++;
console.log(i,j); //2,1

递增”++”运算符的返回值依赖于它相对于操作数的位置。当运算符在操作数之前,称为”前增量”运算符,它对操作数进行增量计算,并返回计算后的值。
当运算符在操作数之后,称为”后增量”运算符,它对操作数进行增量计算,但返回未做增量计算的值。

关系表达式

这一小节的内容其实很丰富,里面的一些基础知识点可能是我们最容易忽略的知识点。

相等和不等运算符

这里面最主要的是分清”==”,”===”这两者之间的不同。

从叫法上来说,第一个叫相等,第二个叫严格相等。关于”===”,首先计算其操作数的值,然后比较这两个值,比较过程中没有任何的类型转换:

  • 如果两个值类型不相同,则它们不相等
  • 如果两个值都是null或者都是undefined,则它们不相等。(在谷歌浏览器测试,以及漠大的w3cplus中这里给出的都是相等,怀疑此处应该是书中的印刷错误)
  • 如果两个值都是布尔值true或者都是布尔值false,则它们相等
  • 如果其中一个值是NaN,或者两个值都是NaN,则它们不相等。NaN和其他任何值都是不相等的,包括其本身
  • 如果两个值为数字且数值相等,则它们相等。如果一个是0,一个是-0,它们同样相等
  • 如果两个值为字符串,且所含的对应位上的16位数完全相等,则它们相等。如果它们的长度或内容不同,则它们不相等。
  • 如果两个引用值指向同一个对象、数组或函数,则它们相等。如果指向不同的对象,则它们是不相等的,尽管两个对象具有完全一样的属性。

相等运算符”==”和严格相等运算符类相似,但是相等运算符的比较并不严格。如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较:

  • 如果两个操作数的类型相同,则和上文所述的严格相等的比较规则一样。如果严格相等,那么比较结果为相等。如果它们不严格相等,则比较结果为不相等。
  • 如果两个操作数类型不同,”==”相等操作符也可能会认为它们相等。检测相等将会遵循如下规则和类型转换:
    • 如果一个值是null,另一个是undefined,则它们相等。
    • 如果一个值是数字,另外一个是字符串,先将字符串转换为数字,然后使用转换后的值进行比较。
    • 如果其中一个值是true,则将其转换为1再进行比较。如果其中一个是false,则将其转换为0再进行比较。
    • 如果一个值是对象,另外一个值是数字或者字符串,则将对象转换为原始值,然后再进行比较。对象通过toString()方法或valueOf()方法转换为原始值。
    • 其他不同类型之间的比较均不相等

可能看起来比较不容易理解,其实了解一点就好了,相等运算符是会将左右两个值进行一次类型转换,然后再比较值。
关于类型转换,在前面的章节中是有介绍的。

比较运算符

这里面值提一点,字符串的比较是区分大小写的,所有的大写的ASCII字母都”小于”小写的ASCII字母。

in运算符

in运算符希望它的做操作数是一个字符换或者可以转换为字符串,希望它的右操作数是一个对象。如果右侧的对象拥有一个名为左操作数值的属性名,那么就返回true。(ps:可能很多时候我们会记错,尤其是像数组那种操作,容易出错)

1
2
3
var ary = ["a","b","c"];
0 in ary //true 相当于a[0]存在
a in ary //false

后面还有几个要点,需要放在单独一章来说,主要是instanceof 与 typeof。