JavaScript 语法介绍

2020-10-25 program web

简单介绍 JavaScript 的核心语法,作为后续的参考手册。

简介

JavaScript 的核心语法部分相当精简,包括了:A) 基本语法,语言标准的操作符、控制结构、语句等;B) 标准库,对数据结构、算法的封装;C) 宿主环境提供的 API 接口,例如操作浏览器、DOM、WEB 等功能。

如下的代码可以直接在浏览器的 Console 标签页中运行,也可以保存文件中,通常有两个位置,会影响其加载顺序:

  • 放在 <head> 中,页面初始化时就会加载。
  • 放在 <body> 中,要等页面初始化完成才去加载。

示例如下。

<!DOCTYPE html>
<html>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <head>
    <title>JavaScript Example</title>
    <script>
    function displayDate(){
      document.getElementById("date").innerHTML=Date();
    }
    </script>
  </head>
  <body>

  <!-- 标签内部使用 -->
  <button type="button" onclick="alert('Hello World!')">Click Me</button>
  <br>

  <!-- 调用头部的内容 -->
  <p id="date">Display Date</p>
  <button type="button" onclick="displayDate()">Now</button>
  <br>

  <!-- 在 Body 中定义 -->
  <p id="demo"></p>
  <script>
    document.getElementById("demo").innerHTML = 15.90;
  </script>
  </body>
</html>

变量类型

通过 var name = value 定义,在 JavaScript 中,是可变类型,也就是说,变量对应的类型可以随时改变。

var foobar;                // undefined
foobar = 5;                // 类型为数字
foobar = "Hello World!";   // 类型为字符串

有六种基本类型:字符串 (String)、数字 (Number)、布尔 (Boolean)、空 (Null)、未定义 (Undefined)、Symbol 。其中,Symbol 是 ES6 引入的一种新的类型,标识独一无二的值。

另外,还包含了三种引用数据类型:对象 (Object)、数组 (Array)、函数 (Function) 。

//----- 字符串
foobar = "Hello World!";   // 可以使用单引号或者双引号
foobar = "Hey, I'm Andy."; // 使用双引号内部可以用单引号,反之亦然

//----- 数字
foobar = 123;              // 不区分整型、浮点,统一采用64Bits浮点表示
foobar = 3.1415926;        // 浮点数
foobar = 1e2;              // 科学记数法,也就是100 123e-3 --> 0.123

//----- 布尔
foobar = true;             // 只能是真 (true)、假 (false)

//----- 数组
foobar = new Array();      // 可以新建数组然后按照序号赋值
foobar[0] = "Hey";
foobar[1] = 3.1415926;
foobar = new Array("Hey", 3.14);
foobar = ["Hey", 3.14];

//----- 对象
foobar = {name:"Andy", age:10};  // 可以通过 foobar.name 或者 foobar["name"] 访问

undefined 是变量声明但未定义时的值,而 null 表示为空值,所以,除了 undefined null symbol 这三种特殊类型,就剩下了五种,可以通过如下方式直接声明。

var foobar = new String;
var foobar = new Number;
var foobar = new Boolean;
var foobar = new Array;
var foobar = new Object;

数组

  • concat() 用于连接两个或多个数组,不会改变现有数组,而是返回连接数组的一个副本。

对象

对象也是最为常用的类型,在定义时比较容易出现歧义,例如 { foobar: 123 } 可以将 foobar 看作代码块中的标签,而 123 作为语句。在定义对象时,最好在大括号外加上圆括号,因为圆括号里只能是表达式,可以确保大括号只能解释为对象,例如 ({ foo: 123 })

另外,在对象中可以直接引用变量,变量名就是 Key 而值就是 Value,如下是一个结合箭头函数的实现。

const addMsg = text => ({
    type: "ADD_MSG",
    text
})
console.log(addMsg("Hello")); // {type: "ADD_MSG", text: "Hello"}

函数

通过 function 关键字声明一个函数,也可以直接赋值给变量,并且 ... 可以变参(参数收集),数组展开(除了赋值)

//----- 基本函数定义
function foobar() {
  alert("Hello World");
}
//----- 使用变量,与上相同
var foobar = function() {
  alert("Hello World");
}

另外,在传参数时,还可以使用解构,这样更加简单清晰。简单来说,解构就是可以快速从对象或数组中提取一些值来创建新变量,如下是一个简单的示例。

const person = {firstName: "Andy", secondName: "Dufresne"}

// 正常使用
function dump(person) {
    return person.firstName + '-' + person.secondName;
}
dump(person);

// 使用解构传参数
function dump({first, second}) {
    return first + '-' + second;
}
dump(person);

箭头函数

在 ES6 中还定义了箭头函数,使的函数定义更加简单,而且关键是 this 就是定义时所指向的对象,而非运行时动态指定,这样代码就很容易理解,如下是几种函数的定义方法。

//----- 箭头函数
var foobar = (a, b) => {
  return a * b;
}
//----- 只有一个表达式、返回值
var foobar = (a, b) => a * b;
//----- 只有一个参数、返回值
var foobar = d => d * 2;
//----- 没有参数
var foobar = () => alert("Hello World");

prototype

与传统面向对象的语言 (例如 C++、Java 等) 不同,在 JavaScript 中,除了基础类型外都是对象,包括了函数,即使在 ES6 中引入了类,但也只是语法糖,那么如何将对象联系起来就成了问题,这也就有了原型和原型链的概念。

当谈到继承时,只有对象 (Object) 一种结构,每个对象都有一个私有属性 __proto__,该属性指向其构造函数的原型对象 (Prototype);而该原型对象同样也有一个自己的原型对象 __proto__,层层向上直到一个对象的原型对象为 null

注意,原型 [[Prototype]] 作为对象的内部属性,无法直接访问,为了方便查看,在 Firefox 和 Chrome 提供了 __proto__ 用来访问,不过这个不是非标准的,ECMA 引入了标准原型访问器 Object.getPrototype(object)

事件广播

包括了冒泡和捕获两种机制,对于两层嵌套的元素来说,捕获会从外到内传播,冒泡则反之。可以通过 element.addEventListener(event, listener, useCapture) 添加对某个 DOM 元素的事件监听,默认是在冒泡阶段捕获。

常用示例

遍历元素

常见的还有 ById ByName 等函数,会返回动态 NodeList 数组。

var blocks = document.getElementsByClassName('highlight');
Array.prototype.forEach.call(blocks, function (e) {
    ... ...
});

新的浏览器还可以使用 querySelector() querySelectorAll() 函数,相对来说要更简单。其中选择方式可以参考 CSS 选择器 的详细介绍。

document.querySelectorAll(".highlight").forEach(function (e) {
    ... ...
});

其它

fetch

基本用法为 fetch("url").then(res=>{},err=>{}); ,不过第一个 then() 函数中返回的是 Response 对象,但没有真正所需的数据,可通过 json() 函数返回一个 Promise 对象,然后再调用 then() 返回的才是真正所需的数据。

fetch('/v1/user')
.then(res => res.json(), err => { console.log(err) })
.then(data => {
    console.log('data is:', data)
}, err => {
    console.log(err)
})

也可以在返回的数据中获取 HTTP 头信息。

fetch('/v1/user')
.then(res => {
    console.log(res.headers.get('Content-Type'));
    return res.json();
}, err => {
    console.log(err)
})

日志打印

可以通过 console.log 将一些格式化信息打印到控制台,如下是常用的参数。

  • %s 字符串。
  • %d %i 整数。
  • %f 浮点数。
  • %o %O object 对象。
  • %c css 样式,会格式化后面信息。

如下是简单示例。

console.log("%c Hello World", "color:red;font-size:24px;");
console.log("%i %d", 10, 100);
console.log("PI is %f", 3.1415926);
console.log("Hello %s", "World");
console.log("Hello %o", document.body);
console.log("%o", {msg:"hello"});
console.log("%O", {msg:"hello"});

参考