javascript权威指南学习笔记(2)--表达式与运算符

1、数组初始化表达式

数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充undefined。如:


var arr = [1,,,,,6]; 
console.log(arr[2]); //打印数组中索引为2的值->undefined

数组直接量的元素列表结尾处可以留下单个逗号,这时并不会创建一个新的值为undefined的元素。

2、运算符

(1)、javascript总是严格按照从左至右的顺序来计算表达式的。
如:

w = x + y * z; 
/*
首先计算表达式w,然后计算x,y,z,然后y的值与z的值相乘,再加上x的值,最后赋值给w所指代的变量或属性。
*/


(2)、所有数字都是浮点型,除法运算的结果也是浮点型。如5/2结果是2.5。
(3)、加号的转换规则优先考虑字符串的连接。(操作数中含有字符串时),但是
“++”或“--”运算符从不进行字符串的连接操作。

in运算符
用于检测某个属性名是否属于某个对象。
当属性名所对应的值初始化为undefined时,检测结果也为true;
当属性名被delete后,再次检测,结果为false。

var point = {    //定义一个对象
		x: 1,
		y: 1
};
console.log("x" in point); //true
console.log("z" in point); //false
console.log("toString" in point); //true:对象继承了toString()方法

instanceof运算符
用于检测某个对象是否是某个类的实例。所有的对象都是Object的实例。

var d = new Date(); //通过Date()构造函数实例化一个新的对象
console.log(d instanceof Date);    //true
console.log(d instanceof Object);     //true
console.log(d instanceof Number);    //false

3、逻辑表达式

(1)、 逻辑与(&&)
原理:运算符首先计算左操作数的值,即“&&”左侧的表达式。如果计算结果是假值,那么整个表达式的结果也一定是假值,因此“&&”会返回左操作数的值,而并不会对右操作数进行计算,将左操作数的值作为整个表达式计算的结果。
反过来,左操作数的值为真值时,会计算右操作数的值,不管是真是假,都会返回右操作的值作为整个表达式计算的结果。

var o = {
		x: 3
};
var p = null;
console.log(o && o.x);     //o和o.x都为真,返回o.x的值3
console.log(p && p.x);    //p为假值,返回p的值null,不去计算p.x

(2)、 逻辑或(||)
原理: 运算符首先计算左操作数的值,即“||”左侧的表达式。如果计算结果是真值,那么整个表达式的结果也一定是真值,因此“||”会返回左操作数的值,而并不会对右操作数进行计算,将左操作数的值作为整个表达式计算的结果。
反过来,左操作数的值为假值时,会计算右操作数的值,不管是真是假,都会返回右操作的值作为整个表达式计算的结果。
最常用的方式是从一组备选表达式中选出第一个真值表达式:

//如果max_width已经定义,直接使用它;否则在preferences对象中查找max_width
//如果没有定义它,则使用一个写死的常量
var max = max_width || preference.max_width || 500;

(3)、 逻辑非(!)
对操作数的布尔值进行求反。
如:x是真值,则!x返回false。

// 对于p和q取任意值,这两个等式都永远成立
!(p && q) == !p || !q
!(p || q) == !p && !q

4、赋值表达式

在大多数情况下,表达式
a op= b (op代表一个运算符)
这个表达式和 a = a op b 是等价的。
特例:下面两个表达式不等价

var data = [1, 2, 3, 4];

for (var i = 0; i < 4; i++) {
    //根据表达式从左到右的运算顺序,++运算法则,先计算data[i]的值为1,i再加1
    //1*2 = 2,求得第一个值,i++,i为3,再次执行循环
    console.log(data[i++] *= 2); //2,6

}

for (var j = 0; j < data.length; j++) {
    //同上,先计算=左边的值后,j+1变为1,然后计算右边的表达式值,
    //此时j为1,data[j]=2,求得第一个值为4,然后j+1变为2,
    //j++,j为3,再次执行循环
    console.log(data[j++] = data[j++] * 2); //4 NaN
}

5、eval()

只有一个参数。如果传入的参数不是字符串,它直接返回这个参数。
作用:解析并运行由javascript源码组成的字符串。
如:

eval("3+2") // 5
eval("var y = 3");     //声明一个新的局部变量y


它使用了调用它的变量作用域环境。直接调用eval()时,它总是在调用它的上下文作用域内执行。其他的间接调用则使用全局对象作为其上下文作用域,并且无法读、写、定义局部变量和函数。如:


var geval = eval;    //使用别名调用eval将是全局eval
var x = "global",
    y = "global";

function f() {     //函数内执行的是局部的eval
    var x = "local";
    eval("x += 'change';");     // 直接eval更改局部变量的值
    return x;     //返回更改后的局部变量
}

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

console.log(f(), x);     // localchange global
console.log(g(), y);    // local globalchanged

在严格模式下,即es5 。代码段以 “ use strict ”开始,eval执行的代码段可以查询或更改局部变量,但不能在局部作用域中定义新的变量或函数。同时,eval被列为保留字,不能用一个别名覆盖eval()函数,并且变量名、函数名、函数参数或异常捕获的参数都不能取名为“eval”。

6、delete运算符

delete是一元操作符,它用来删除对象属性或数组元素。
如:

var o = { x : 1, y : 2};     //定义一个对象
delete o.x;                    //删除一个属性
"x" in o                    //false 属性不存在

var a = [1,2,3];            //定义一个数组
delete a[2];                //删除索引为2 的数组元素
2 in a;                    //false 索引为2的数组元素不存在
a.length                   // 3, 数组长度并没有改变,因为其它值的索引并没有改变

但是,一些内置核心和客户端属性是不能被删除的,通过var语句声明的变量也不能删除,function语句定义的函数和函数参数也不能删除。
在es5严格模式下,如果删除的操作数非法,将抛出一个语法错误的异常,同时删除不可配置属性时会抛出类型错误异常。在非严格模式下,只是简单的返回false,并不会报错。

var o = { x:1, y:2};  
delete o.x;    //true  
typeof o.x;    //undefined 属性不存在  
delete o.x;     //true 不存在属性  
delete o;    //false var声明不能删除  
  
delete 1;    //true 不是左值(属性)  
this.x = 1;    //全局定义一个属性  
delete x;     //true(非严格模式下) 严格模式下使用 delete this.x












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值