语句

编程语言的语句大多都是类似的,本篇只列举常用的一些 JavaScript 语句。

if-else语句

  1. if (10 > 5) {
  2. console.log(10);
  3. } else {
  4. console.log(5);
  5. }

do-while语句

do-while 循环体内的代码至少会被执行一次。

  1. var i = 10;
  2. do {
  3. i++;
  4. } while (i < 5)
  5. console.log(i); // 输出: 11

while语句

  1. var i = 0;
  2. while(i < 10){
  3. i++;
  4. }
  5. console.log(i); // 输出: 10

while 常用于逐个取出数组元素:

  1. var arr = [1, "2", true];
  2. console.log(arr); // 取出前
  3. while(arr.length > 0) {
  4. console.log(arr.shift()); // shift()方法会把数组第一个元素取出
  5. }
  6. console.log(arr); // 取出后

for语句

for 与 while 功能相似。

  1. for(var i = 0; i < 10; i++) {
  2. // 操作
  3. }
  4. console.log(i); // 输出: 10

for常用于遍历数组元素:

  1. var arr = [1, 2, 3];
  2. for(var i = 0; i < arr.length; i++) {
  3. console.log(arr[i]); // 通过索引号访问数组元素
  4. }

for-in和for-of语句

  • for-in遍历的是索引(键名),for-of遍历的是值;
  • for-in可以遍历对象,且可遍历自身及原型上可枚举的属性;
  • for-of只能遍历具有迭代器接口的数据,如果想遍历对象可以使用Object.keys()将对象的键名生成一个数组。

switch语句

  1. var n = 7;
  2. switch (n) {
  3. case 1: console.log("星期一"); break;
  4. case 2: console.log("星期二"); break;
  5. case 3: console.log("星期三"); break;
  6. case 4: console.log("星期四"); break;
  7. case 5: console.log("星期五"); break;
  8. case 6: console.log("星期六"); break;
  9. default: console.log("星期天");
  10. }

switch 括号里面的值和 case 值相等的话就执行 case 后的代码,否则进行下一次比较直到 defalut 为止。case 后跟的值可以是表达式。

  1. var a2 = 4;
  2. switch (true) {
  3. case a2 < 5: console.log("小于5"); break;
  4. case a2 < 10: console.log("小于10"); break;
  5. default: console.log("其他");
  6. }

变量

var

声明变量使用的是 var 关键字,JavaScript 是弱类型语言,也就是说用 var 声明的变量可赋任何类型的值。

JavaScript 解释器有自己的内存管理机制,可以自动对内存进行垃圾回收,当不再有任何引用指向一个对象,解释器就会知道这个对象没用了,然后自动回收掉它所占用的内存资源。

变量提升

变量提升(声明提前)就是将所有用var声明变量的语句提升到代码头部,其底层原理是 JavaScript 引擎的工作方式是先解析代码,获取所有被声明的变量,然后再执行,也就是分为预处理和执行这两个阶段。

函数提升优先于变量提升,函数提升会将整个函数挪到作用域顶部,变量提升只将声明提到作用域顶部。

函数

JavaScript 中的函数是特殊的变量,定义函数使用的是 function 关键字,后跟一组参数以及函数体。

  1. function add(a, b, c) {
  2. console.log(a + b + c);
  3. }

可以通过 return 关键字在函数体中返回值,return 后的内容不会被浏览器识别和执行。

任何类型的变量都可以作为参数传入函数,如果将 Object 类型的数据传入,传进函数的是原对象的地址(或者说引用),这个地址赋值给了形参(形参看做局部变量),例如:

  1. function changeObjProperty(a) {
  2. // 改变对应地址内的对象属性值
  3. a.siteUrl = "http://www.baidu.com";
  4. // 变量a指向新的地址 以后的变动和旧地址无关
  5. a = new Object();
  6. a.siteUrl = "http://www.google.com";
  7. a.name = 456;
  8. }
  9. var webSite = new Object();
  10. webSite.name = '123';
  11. changeObjProperty(webSite);
  12. console.log(webSite); // {name: 123, siteUrl: 'http://www.baidu.com'}

arguments

函数内存在一个 arguments 类数组对象用于包含函数调用时传入的参数,arguments.length 可以获取传入参数的个数,arguments[index] 可以访问指定索引号的参数。

JavaScript 对函数具体传入的参数个数没有限制,形参和实参个数不一定相等。

  1. function add(a, b) {
  2. console.log(a === arguments[0]); // 返回true
  3. console.log(arguments.length);
  4. }
  5. add(1, 2, 3); // 可以传入更多参数

匿名函数

定义时不带函数名的函数称为匿名函数,根据场景的不同,匿名函数又被附加上其他名字,例如,以下代码中的匿名函数被当做一个对象的属性,此时其被称为”方法”——say:

  1. var obj = {
  2. name: 'ABC',
  3. say: function(name) {
  4. console.log('I am ' + name);
  5. }
  6. }

匿名函数可以作为参数传入其他的接口函数,此时其被称为”回调函数”:

  1. function requestData(callback) {
  2. // Ajax handle...
  3. if (callback) callback();
  4. }
  5. // 传入的匿名函数称为回调函数
  6. requestData(function() {
  7. console.log('GET.');
  8. });

非匿名自执行函数,函数名只读,如果要重写函数对应的函数名,严格模式下会报错,一般模式下会失效:

  1. var b = 10;
  2. (function b() {
  3. 'use strict'
  4. b = 20;
  5. console.log(b);
  6. })(); // "Uncaught TypeError: Assignment to constant variable."

作用域

JavaScript 的函数作用域是指在函数内部声明的所有变量在函数体内始终是可见的,这意味着变量在声明之前甚至是可用的,JavaScript 的这个特性被非正式地称为”声明提前”或者”变量提升”。

例如:

  1. var name = 'WJT20';
  2. function call() {
  3. console.log(name); // undefined
  4. var name = 'John';
  5. console.log(name); // "John"
  6. }
  7. call();

函数call()内引用的 name 变量之所以是 undefined 而不是”WJT20”,是因为 name 的声明被提升到函数作用域的最顶部,也就是说实际上,以上代码的执行情况等同于以下代码:

  1. var name = 'WJT20';
  2. function call() {
  3. var name;
  4. console.log(name); // undefined
  5. name = 'John';
  6. console.log(name); // "John"
  7. }
  8. call();

由于 JavaScript 没有块级作用域,因此将变量声明放在函数体顶部,而不是将声明靠近放在使用变量之处,这种做法使得源代码非常清晰地反映真实的变量作用域。

每一段 JavaScript 代码(全局代码或函数)都有一个与之关联的作用域链,这个作用域链是一个对象列表或者链表,这组对象定义了这段代码”作用域中”的变量。当 JavaScript 需要查找变量 x 的值时(此过程被称为”变量解析”),它会从链中的第一个对象开始查找,如果这个对象有一个名为 x 的属性,则会直接使用这个属性的值,否则 JavaScript 会继续查找链上的下一个对象,以此类推,如果作用域链上没有任何一个对象含有属性 x,那么就认为这段代码的作用域链上不存在 x,并最终抛出一个引用错误异常。