定义
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,然后输入合适的名称:
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
。
// 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.querySelector
和 alert
是浏览器内置的函数。下面代码演示的是如何自定义函数:
function multiply(num1, num2) {
return num1 * num2;
}
2.6 事件
事件能为网页添加真实的交互能力。它可以捕捉浏览器操作并运行一些代码做为响应。最简单的事件是点击事件,鼠标的点击操作会触发该事件。
<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 整体流程
- 先清空call stack中的同步代码
- 执行微任务队列中的微任务
- 尝试DOM渲染
- 触发Event Loop反复询问callbackQueue中是否有要执行的语句,有则放入call back继续执行
4. 原型
4.1 构造函数
构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立的。
构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。另外就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用。
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, 它指向函数对象。
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中的类