Skip to content
章节导航

定义

JavaScript(缩写:JS)是一门完备的动态编程语言。当应用于 HTML 文档时,可为网站提供动态交互特性。由布兰登·艾克(Brendan Eich,Mozilla 项目、Mozilla 基金会和 Mozilla 公司的联合创始人)发明。

1. 什么是js

JavaScript 的应用场合极其广泛,简单到幻灯片、照片库、浮动布局和响应按钮点击,复杂到游戏、2D/3D 动画、大型数据库驱动程序等等。

JavaScript 相当简洁,却非常灵活。开发者们基于 JavaScript 核心编写了大量实用工具,可以使 开发工作事半功倍。其中包括:

  • 浏览器应用程序接口(API)—— 浏览器内置的 API 提供了丰富的功能,比如:动态创建 HTML 和设置 CSS 样式、从用户的摄像头采集处理视频流、生成 3D 图像与音频样本等等。
  • 第三方 API —— 让开发者可以在自己的站点中整合其它内容提供者(Twitter、Facebook 等)提供的功能。
  • 第三方框架和库 —— 用来快速构建网站和应用。

2. 快速入门

2.1 变量

变量 (en-US) 是存储值的容器。要声明一个变量,先输入关键字 let 或 var,然后输入合适的名称:

js
let myVariable = 'Hello World'

2.2 数据类型

注意变量可以有不同的数据类型 :

  • 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol
  • 引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。

数据类型

变量解释示例
String字符串(一串文本):字符串的值必须用引号(单双均可,必须成对)扩起来。let myVariable = '李雷';
Number数字:无需引号。let myVariable = 10;
Boolean布尔值(真 / 假): true/false 是 JS 里的特殊关键字,无需引号。let myVariable = true;
Array数组:用于在单一引用中存储多个值的结构。let myVariable = [1, '李雷', '韩梅梅', 10];
Object对象:JavaScript 里一切皆对象,一切皆可储存在变量里。这一点要牢记于心。let myVariable = document.querySelector('h1');

2.3 运算符

运算符 (en-US) 是一类数学符号,可以根据两个值(或变量)产生结果。以下表格中介绍了一些最简单的运算符,可以在浏览器控制台里尝试一下后面的示例。

运算符解释符号示例
将两个数字相加,或拼接两个字符串。+6 + 9;
"Hello " + "world!";
减、乘、除这些运算符操作与基础算术一致。只是乘法写作星号,除法写作斜杠。-, *, /9 - 3;
8 * 2;
9 / 3;
赋值运算符为变量赋值(你之前已经见过这个符号了)=let myVariable = '李雷';
等于测试两个值是否相等,并返回一个 true/false (布尔)值。===let myVariable = 3;
myVariable === 4; // false
不等于和等于运算符相反,测试两个值是否不相等,并返回一个 true/false (布尔)值。!==let myVariable = 3;
myVariable !== 3; // false
取非返回逻辑相反的值,比如当前值为真,则返回 false。!let myVariable = 3;
!(myVariable === 3); // false

2.4 条件语句

条件语句是一种代码结构,用来测试表达式的真假,并根据测试结果运行不同的代码。一个常用的条件语句是 if ... else

js
// if...else
let num = 10;
if (num > 0) {
  alert('正数');
} else {
  alert('负数');
}
// switch...case
const day = new Date().getDate()
switch (day) {
    case 0, 6:
        alert('周末');
    default:
        alert('工作日');
}

2.5 函数

函数用来封装可复用的功能。如果没有函数,一段特定的操作过程用几次就要重复写几次,而使用函数则只需写下函数名和一些简短的信息。

document.querySelectoralert 是浏览器内置的函数。下面代码演示的是如何自定义函数:

js
function multiply(num1, num2) {
    return num1 * num2;
}

2.6 事件

事件能为网页添加真实的交互能力。它可以捕捉浏览器操作并运行一些代码做为响应。最简单的事件是点击事件,鼠标的点击操作会触发该事件。

html
<button id="btn1">click</button>

<script>
    const btn1 = document.getElementById('btn1')
    // 只会触发最后定义的
    btn1.onclick = () => {
        console.log('clicked me')
    }
    // 添加多少个,会触发多少次
    btn1.addEventListener('click', () => {
        console.log('clicked me')
    })
</script>

3. 事件循环

3.1 定义

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

3.2 微任务和宏任务

在JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。

  • MacroTask(宏任务)setTimeout、setInterval、I/O、UI Rendering。
  • MicroTask(微任务) Process.nextTick(Node独有)、Promise、Object.observe(废弃)、MutationObserver

3.3 执行过程

  • 同步代码,调用栈执行后直接出栈
  • 异步代码,放到Web API中,等待时机,等合适的时候放入回调队列(callbackQueue),等到调用栈空时eventLoop开始工作,轮询
  • 微任务执行时机比宏任务要早

3.4 整体流程

  1. 先清空call stack中的同步代码
  2. 执行微任务队列中的微任务
  3. 尝试DOM渲染
  4. 触发Event Loop反复询问callbackQueue中是否有要执行的语句,有则放入call back继续执行 整体流程

4. 原型

4.1 构造函数

构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立的。

构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。另外就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用

js
function Person(name, age, gender) {
    this.name = name
    this.age = age
    this.gender = gender
    
    this.getInfo = function () {
        return `${name} is a ${age} years old ${gender}`
    }
}
Person.prototype.getName = function () {
    return this.name
}
const p1 = new Person('lzugis', 18, 'boy')
console.log(p1.getInfo())

4.2 原型

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。 原型

4.3 __proto__和constructor

每一个对象数据类型(普通的对象、实例、prototype......)也天生自带一个属性__proto__,属性值是当前实例所属类的原型(prototype)。原型对象中有一个属性constructor, 它指向函数对象。

js
function Person() {}
 var person = new Person()
 console.log(person.__proto__ === Person.prototype)//true
 console.log(Person.prototype.constructor===Person)//true
 console.log(Object.getPrototypeOf(person) === Person.prototype) // true

4.4 原型链

在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。

举例说明:person → Person → Object ,普通人继承人类,人类继承对象类

当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。

我们可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性;使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true 原型链

5. es6

5.1 概念

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

5.2 新特性

  • 变量声明:const和let
  • 模板字符串
  • 箭头函数
  • 函数的参数默认值
  • Spread / Rest 操作符...
  • 对象和数组解构
  • for...of 和 for...in
  • ES6中的类