这是一个“然并卵”的问题,由于没有人愿意在代码中给本身找这种麻烦,看到书上讲到这个问题忍不住想顺势总结下,就从表达式提及吧。php
在js中,同通常的语言同样,表达式分不少种。c++
var arr1 = []; //空数组 var arr2 = [1,2,3+5]; var arr3 = [1,,3,,6]; var obj1 = {}; //空对象 var obj2 = {x:3, y:5};
逗号之间能够空着不写,js默认将其定义为undefined,而对象的属性在有空格时须要加引号以构成字符串的属性名,属性值能够是任意类型。嵌套定义也能够。经过这个中直接声明而来的,通常将其称为原始值或直接量,由于它们与真正经过new关键字获得的对象数组有一点差异。数组
var vl = function(){ document.write("function to a var.<br/>"); }; vl();
var arr = [1,2,3]; document.write(arr[0]+"<br/>"); var obj = {x:1, y:5}; document.write(obj.x+" "+obj["y"]);
function fun(){ ; } fun(); //函数调用 function Game(name){ //构造函数 this.name = name; this.fly = function(){;} } var flappy_bird = new Game("flappy_bird"); flappy_bird.fly(); //方法调用
相似于对对象属性的引用,方法调用也会先计算点号左边是不是一个对象,不是对象的话将会抛出类型错误。app
var arr = new Array(1,2,3); var o = new Object; var date = new Date();
还有跟运算符相关的算术表达式、关系表达式、逻辑表达式等、赋值表达式等,值得注意的是js的逻辑表达式并不必定返回布尔类型的true和false,如ide
var ret1 = 5 && [1,2,3]; document.write("ret1: type=>"+typeof(ret1)+" val:"+ret1+"<br/>"); var ret2 = 0 || 5; document.write("ret2: type=>"+typeof(ret2)+" val:"+ret2+"<br/>");
输出 函数
可是在其余语言,好比php中,逻辑表达式的最终结果必定是布尔型的,这点须要区别。this
咱们更容易忘记的是最简单的情形:原始表达式。所谓原始表达式是表达式的最小单位,它不在包含其余表达式,它就是最简单的常量、变量、原始值或关键字,如spa
//原始值 15; "hello"; /[A-Z]\d+/; //关键字 null; false; //变量 index; sum;
跟运算符扯上关系的,确定要考虑运算符的优先级、结合性,优先级高的先运算,优先级高的先运算,还要看看是从左到右仍是从右到左,好比常常用的连续赋值code
var a = b = c = 1;
由于赋值运算符的结合性是从右到左,因此上面又等价于下面这样的:对象
var a = (b = (c = 0));
最后一点是运算符的运算顺序,一般咱们只须要考虑优先级与结合性就够了,谈到运算顺序,它涉及的的是子表达式(父子关系老是相对的),以下面一段计算式
w = x + y * z
子表达式就是w、x、y、z,由于是最简单的变量,因此它们是原始表达式,js是按照从左到右的顺序来计算子表达式的,这里先依次计算w、x、y、z的子表达式的值,而后根据优先级和结合性,先计算y+z的值,再与x相加,将结果赋值给表达式w所指代的某个变量。
而咱们通常碰到的状况是,计算x子表达式的时候,对y不会产生什么影响,一旦产生了影响(使用特殊运算符),如改变了y子表达式的值,这称为运算符的反作用(side effect)。能改变子表达式的值,确定要对它赋值,因此通常具备赋值做用的运算符容易产生反作用,严格的说等号具备反作用,固然通常用等号确定就是要改变等号左边表达式的值,谈个毛线反作用。
回到(i++)+(++i),使用具备隐式赋值做用的自增运算符,自减天然也算,就产生反作用了,前面的先各一个i子表达式的初始值,假设i初始值为1,而后计算i++时,因为自增缘由,自增计算过程当中对 i 进行了赋值运算,i++这个总体表达式的值仍为1,再计算++i 时,i 这个子表达式的值已是2(前面的赋值改变了它的大小),因此后面 i++的值是3,总的结果就是4。其余的,c/c++等的理解方式几乎相同。
放佛又回到曾今被老师坑惨的c语言考试题=_=