Skip to content

第四章:表达式和运算符

Lixiang Mu edited this page Feb 6, 2014 · 2 revisions

####**1.**数组是可以嵌套的,即 数组的元素也可以是数组

####**2.**数组直接量中的列表逗号之间的元素是可以省略的,这时省略的空位值是undefined

例:
var m = [1,,,,5]; //此时m[1],m[2],m[3]的值为undefined
var n = [1,,,,5,,]; //n的length为6, n[5]的值也是undefined

数组中末尾后也可留下逗号,但不会创建新的undefined值
逗号之间是空位 则值为undefined。注意是 逗号之间 参见上例中的数组n

####**3.**对象也是可以嵌套的,即对象的属性值也可以是对象

####**4.**对象直接量中的属性名称可以是字符串,而不是标识符

例:
var side = 1; var p = {x:1, y:2};
var square = {"upperLeft": {x: p.x, y: p.y},
			  "lowerRight": {x: p.x+side, y: p.y+side}
			 }

上例中属性名既有标识符(如 x、y),也有字符串(如 "upperLeft"、"lowerRight")

####**5.**函数定义表达式

例:
var square = function(x) { retrun x*x;}

####**6.**属性访问语法 .[]

a.x
a["x"] // []中为属性名的字符串形式或数组的索引

例:
var Q = {x:1, y:{z:3}};
var a = [Q,4,[5,6]];
Q.x;  		  //1
Q.y.z;  	  //3
Q["x"];  	  //1
a[0].x;  	  //1
Q["y"]["z"];  //3
a[2][1];      //6
a[2]["1"];    //6

当属性名是计算而得的值而非固定值的时候,要使用[]

####**7.**对象创建表达式。 new 一个构造函数

构造函数无返回值

####**8.**生疏运算符摘要

  • delete 删除属性
  • typeof 检测操作数类型
  • instanceof 测试是对象是否为类的实例
  • in 测试属性是否存在

####**9.**函数调用,属性访问表达式的优先级非常高。比typeof还高。

可以用括号()改变运算优先级
不确定优先级时最好用括号

####**10.**一元操作符、赋值、三元运算符 都具有右结合性(从右至左算)

####11. 0/0结果是NaN

####12. % 求余运算也适用于小数

例:
6.3 % 3.1 = 0.1 

####13. +加号 两个操作数会转化为数字或字符串。

若一个是字符串 则另一个也会转化为字符串

例:
2 + null       //2       null转化为0
2 + undefined  //NaN     undefined转化为NaN

注意:
1 + 2 + "mlx"  // "3mlx"
1 + (2 + "mlx")  // "12mlx"

####**14.**严格相等 "===" 首先计算操作数的值,然后比较,比较过程没有任何类型转换。

  • 若类型不同,则不相等。

  • 若两个值都是nullundefined,则相等。

  • 若两个值均是布尔值truefalse,则相等。

  • 若一个为NaN或两个均为NaN,则不相等。

  • 若两个操作数均为数字且数值相等,则相等。且 0 === -0

  • 若两个操作数均为字符串且对应位置字符的十六位数编码完全相等,则相等。

  • 两个引用指向同一个对象、数组或函数,则他们相等。否则不相等。

    • 即使两个对象的属性、方法完全一样,也不相等,因为是不同的对象。

####**15.**相等比较 "=="

  • 类型相同值相等,则相等。
  • 类型不同:
    • 若一个为null,另一个为undefined,则相等。
    • 若一个为数字,另一个为字符串,现将字符串转化为数字再比较。
    • 若其中一个为true/false, 将其转化为1/0, 然后比较。
    • 若一个是对象,另一个是数字或字符串,先将对象转化为原始值然后比较。

####**16.**比较操作符的操作数可能是任意类型,但只有数字和字符串才能真正执行比较操作。故其他类型必须按规则转换,然后比较。

####**17.**字符串比较是按字符比较

例:
"ab" < "ac"  // true
"ca" < "bb"  // false

第一个字符相等,比较第二个,依次,在不等时返回比较结果。

####18.0-0相等,Infinity比其他任何数字都大, -Infinity比其他任何数字都小。若其中有一个操作数是NaN则比较结果为false

####**19.**加号运算符偏向于将操作数转化为字符串。比较运算符偏向于将操作数转化为数字。

####**20.**大于等于,小于等于 中的等于不依赖于相等或严格相等。>=只是“不小于” <=只是“不大于”

####21.in运算符的左操作数是一个字符串或可以转为字符串,其右操作数是一个对象。

例:
var P = {x:1, y: 2};
"x" in P          //true   x为P的属性
"z" in P          //false  z不是P的属性
"toString" in P   //true   toString方法P也有,是继承的

var d = [7, 8, 9];
"0" in d 		  //true  "0"是索引,即相当于对象的属性名
1 in d			  //true  数字1转化为字符串"1", 也在d中
3 in d            //false d中没有索引3

####22.instanceof的左操作数不是对象的话,返回false, 目的是判断谁是谁的实例

####**23.**原型链是关于继承的

####24.&&的两个操作数为非布尔值时,关于&&的返回值。

例:
var a = {x: 2};  var p = null;
var b = a && a.x  //a && a.x 结果为true  b的值为2
var c = a && a.z  //a && a.z 结果为false c为undefined
类似的 p && p.x //false  返回值是null即为p的值。

||的运算返回值和&&类似

####**25.**关于 ||的经典用法,通常在函数体内部

例:
function copy(o,p){
	p = p|| {}; //若p没有被传入对象,则初始化为p为{}	
	...
}

####26. !运算符总是返回 truefalse

####**27.**直接调用eval()时,它总是在调用它的上下文作用域内执行,其他间接调用(指给eval取别名)则使用全局对象作为上下文作用域,并且无法读、写、定义局部变量和函数。

例:
var geval = eval;	          //使用别名调用eval将是全局eval.
var x = "mlx", y = "brj";	  //两个全局变量
function f(){	              //函数内执行的是局部eval
	var x = "local";
	eval("x +='changed';")	  //直接eval更改局部变量的值
	return x;
}

function g(){				  //该函数执行全局eval
	var y = "local";
	geval("y +='changed';");  //间接调用eval 改变全局变量的值
	return y;				  //返回未更改的局部变量
}

####**28.**用户通过var声明的变量不能delete,同样,通过function定义的函数和函数参数也不能delete

####**29.**严格模式下,删除不可配置的属性时,会抛出一个类型错误异常,非严格模式只是简单的返回false