-
Notifications
You must be signed in to change notification settings - Fork 0
第四章:表达式和运算符
####**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.**严格相等 "===" 首先计算操作数的值,然后比较,比较过程没有任何类型转换。
-
若类型不同,则不相等。
-
若两个值都是
null
或undefined
,则相等。 -
若两个值均是布尔值
true
或false
,则相等。 -
若一个为
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. !
运算符总是返回 true
或false
####**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
by @zhulinpinyu 👍