说明

  前面的两篇博客介绍了js中的基本知识中的变量类型、标识符等。这篇博客主要谈表达式以及运算符。

原始表达式

  原始表达式就是表达式中最小的,不能在分割的表达式,一般指变量、常数直接量、关键字(true、false、null、this),这里需要注意的是undefined是一个全局变量,而不是关键字。

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

  数组初始化表达式是一个方括号,中间放置数组中的元素,元素间用逗号分割。元素可以是表达式、数组、空。

 []    //一个空数组,数组里面没有元素
[1+2,3+4] //一个拥有两个元素的数组,第一个是3,第二个是7。
[[1,2,3],[4,5,6],[7,8,9,]] //数组中的元素还可以是数组。
[1,,,,5] //数组中的元素可以为空,这时空位会填充值undefined。

  在执行var a=[1,,,,5]这条语句后,在chrome中表现为下图所示:

  对象初始化表达式和数组初始化表达式非常类似。

 var stu={name:"张三", age:15};    //定义一个拥有两个属性的对象。

  上面这行初始化对象的表达式类似于下面的数组,事实上js也确实支持这种写法访问对象中的属性。

 stu["name"]="张三";
stu["age"]=15;

  如果你学过java那么上面那句var stu={name:"张三", age:15};可以很容易的写成下面的java代码:

 class Student{
String name;
int age; Student(String name, int age){
this.name=name;
this.age=age;
}
} Student stu=new Student("张三", 15);

  不过js可以完美支持多层的内部类,而java却对内部类有好多限制。

属性访问表达式

  在js中,属性访问有①expression.identifier、②expression[expression]这两种方式。其中第一种虽然方便却只能用于对象,而且要求访问的属性(identifier)不能是关键字、不能含有空格、不能是数字。而第二种访问方式不仅支持对象还能用于数组,并且用于对象访问自己的属性时没有第一种那么多的限制。

 var o={x:1, y:{z:3}};
var a=[o, 4, [5, 6]];
o.x //1:访问o的x属性
o.y.z //3:访问o的y的z属性
o["x"] //1:访问o的x属性
a[1] //4:访问a的索引为1的元素
a[2]["1"] //6:访问a[2]中的索引为1的元素
a[0].x //1:通过访问a[0]得到o,再访问o的x属性

运算符

  js所支持的运算符如上图所示,学过其它编程的同学基本上看上一眼就知道了。这里只对需要注意的部分做出说明。在基本算术运算符(加减乘除和求余)只有加法是相对有难度的,因为有时候它是加法,而有时候它又是字符串连接符,具体用法可概括为只有+运算符两边都是数字才是加法,更详细的用法请参考这篇博客。此外还需要谈的就是求余运算符,其运算结果的符号和左操作数相同,即5%1=1、-5%1=-1。

  在js的位运算时,会有一个隐式转换过程。默认情况下js中的数字都是存储为64位浮点数格式,在位运算的时候会转换为32位整数,所以隐式转换会截断小数部分和整数中超过32位能表示的部分。此外NaN、infinity和-infinity会转换为0。

  关于等于(==)运算符和严格等于(===)运算符请参考本系列教程的第一篇

in运算符

  in运算符希望它的左操作数是一个字符串或者能转换为字符串,希望它的右操作数是一个对象。如果右侧对象拥有一个名为左操作数的属性则整个in表达式返回true。

 var point={x:1, y:1};
"x" in point //true:对象中有一个名为x的属性
"z" in point //false:对象中不存在一个名为z的属性
"toString" in point //true:对象继承了toString()方法 var data=[7, 8, 9];
"0" in data //true:数字包含下标为0的元素
1 in data //true:数字转换为字符串
3 in data //false:没有索引为3的元素

&&与||

  学过C和java等语言的同学应该知道这两个运算符有一个特性就是短路,这个特性在js中也同样存在,习惯性利用这种特性为函数提供默认值。

 function copy(o, p){
o.p = p || {};
}

  上面的代码中,如果copy函数被调用的时候p形参有值,则将p复制给o.p,否则将默认值{}复制给o.p。

表达式计算

  在js中存在一个函数叫eval(),虽然这是一个函数,但一般被当成运算符来对待。一般来说函数是可以起别名的,比如var f=eval;再通过f调用eval函数。但是一般不推荐对eval函数起别名,ECMAScript3标准甚至直接禁止对eval函数起别名,所以说它几乎被当成运算符对待。之所以这样是因为这涉及到代码优化的问题,如果允许对eval函数起别名将严重影响代码的优化过程。

  上面谈了eval的特点,现在来说一下它的作用。这个函数只有一个参数,且一般是字符串。如果传入的参数是字符串,js解释器会把这个字符串当成js代码来执行,且其执行环境为直接调用这个eval函数的上下文(下面将详细解释),如果其传入的参数不是字符串,则eval函数直接返回这个参数值。

 var global=1;
var foo = function(ele){
var local = 2;
eval(ele);
console.log(where);
}
foo("console.log(global);console.log(local);var where='I am here!';");
console.log(where);

  上面这行代码的执行结果(在chrome中)如下图所示:

  根据上面所说的eval的执行环境为直接调用eval的上下文,在上图显示的结果中为第8行所处的上下文,这样的话eval自然能访问global和local变量,但是其定义的where变量只能让foo函数内部且在第8行以后的代码访问,这样以来第9行代码能正确执行,而第12行代码抛出异常。

  前面谈过ECMAScript3禁止对eval起别名,但是现实中大多数解释器的实现并非如此,之后的ECMAScript5标准也允许别名调用,但规范了其行为。当eval被别名调用时,其运行环境永远为全局环境,与其调用者环境没有关系,也就是说间接调用(别名调用)无法读、写、定义局部变量。

 var geval = eval;
var x = "global", y = "global";
function f(){
var x="local";
eval("x += ' changed';");
return x;
}
function g(){
var y="local";
geval("y += ' changed';");
return y;
}
console.log(f(), x);
console.log(g(), y);

  上面代码执行的结果(在chrome中)为:

JavaScript基础入门教程(三)的更多相关文章

  1. JavaScript基础入门教程(四)

    说明 前面三篇博客介绍了js中基本的知识点,包括变量类型及其转换.表达式.运算符等小知识点,这篇博客主要讲的是对象.如果你学过java等语言,你也许在下文的阅读中发现在js中的对象与java中的对象存 ...

  2. JavaScript基础入门教程(一)

    本系列教程的说明 本教程说白了可以说是我自己学习JavaScript的笔记,主要内容参考自<JavaScript权威指南>,部分内容可能来自互联网,本系列教程假设学者之前学过c或者其它的编 ...

  3. JavaScript基础入门教程(六)

    说明 在看这篇博文之前还是希望读者阅读本系列前几篇文章,还有就是该系列需要读者拥有其它语言的编程基础,一些基本的知识点,比如什么是形参和实参将不再赘述.这篇博文主要讲函数. 函数的定义 在js种支持函 ...

  4. JavaScript基础入门教程(五)

    说明 本系列博客的第一篇已经说明了,要求阅读者需要具有其它语言的编程基础,所以关于组数的基础部分本篇博客将不再赘述,主要讲js中数组的特性. 创建数组 数组的创建主要有两种方法,一种是数组直接量,还有 ...

  5. JavaScript基础入门教程(二)

    说明 前一篇博客介绍了js以及一些关于js基本类型的简单知识,本篇博客将详细介绍js的基础类型,捎带介绍对象类型,更详细的对象类型的说明将后续再讲. js中类型的说明 js中的类型分为基本类型和对象类 ...

  6. 无废话ExtJs 入门教程三[窗体:Window组件]

    无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...

  7. React Native基础&入门教程:初步使用Flexbox布局

    在上篇中,笔者分享了部分安装并调试React Native应用过程里的一点经验,如果还没有看过的同学请点击<React Native基础&入门教程:调试React Native应用的一小 ...

  8. Linux基础入门教程

    Linux基础入门教程 --------- Linux学习路径 Linux学习者,常常不知道自己改怎么学习linux:Linux初级,也就是入门linux前提是需要有一些计算机硬件相关的知识或是有一下 ...

  9. JavaScript 基础入门

    JavaScript 基础入门   JavaScript 的组成 JS 由三部分组成,它们分别是:ECMAScript.DOM.BOM. ECMAScript     因为网景开发了JavaScrip ...

随机推荐

  1. 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6150 Vertex Cover 二分图,构造

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6150 题意:"最小点覆盖集"是个NP完全问题 有一个近似算法是说—每次选取度数最大 ...

  2. plus.networkinfo.getCurrentType()

    HTML5+API device Device Device模块管理设备信息,用于获取手机设备的相关信息,如IMEI.IMSI.型号.厂商等.通过plus.device获取设备信息管理对象. 对象: ...

  3. windows访问linux共享文件夹

    1.windows的网上邻居,是通过smb协议来共享信息的,如果需要给访问linux上的共享目录被windows访问到,需要linux有smb协议 sudo apt-get install samba ...

  4. MYSQL表中向SET类型的字段插入值时值之间不能有空格

    MYSQL 中有一种数据类型是 SET,首先我们查看一个包含 SET 类型字段的表结构: 接下来我们向表中插入数据: 按照上面的语句插入数据发现报错了,于是去掉了插入值之间的空格,然后插入成功:

  5. 无锁的对象引用:AtomicReference

    http://www.dewen.net.cn/q/9588 首先volatile是java中关键字用于修饰变量,AtomicReference是并发包java.util.concurrent.ato ...

  6. pku 2777(经典线段树染色问题)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41202   Accepted: 12458 Des ...

  7. linux下c获取时间

    头文件 #include "sys/time.h" 结构体 struct timezone { int tz_minuteswest; /*格林威治时间往西方的时差*/ int t ...

  8. 这种文件别打开, 大小不足1KB, 却可以让你电脑瘫痪

    今年6月份,抖音表白代码火了,不足1kb的txt文件,玩出了新花样.可是你知道吗,这种非常“浪漫”的表白方式,其实存在着很大的风险,甚至会让你的电脑直接瘫痪. 首先,先说一下所谓的表白代码是怎么回事. ...

  9. Supervisor-类unix系统下的进程控制工具

    如果你的英文足够好,请看官网的文档:http://supervisord.org/introduction.html 简介: Supervisor 类unix系统下的进程控制工具. 特性: 1.配置简 ...

  10. es6解构赋值总结

    数组的解构赋值 1.简单的赋值方式 2.多维数组解构赋值 3.默认值,只有当右边对应位置为undefined时候才会选择默认(null不属于undefined) 4.左右不对等,会相应的对号入座,没有 ...