1 HTML中的JavaScript
js
引用文件可以放在两个位置,一种是html中的head
中,一种是html中的body
中;放置在这两个位置,有何区别呢?
1.1 使用<script>
元素的方式
1.1.1 放置在 head 中
引用example.js
文件,将其放置在head
中的script
中;
浏览器需要将example.js
文件下载完成,解析完成之后,才会开始渲染页面,这会导致刚打开页面,页面呈现空白。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style></style>
<script src="example.js"></script>
</head>
<body>
<!-- 页面内容 -->
<script></script>
</body>
</html>
1.1.2 放置在 body 中
引用example.js
文件,将其放置在body
中的script
中;不会影响页面渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style></style>
</head>
<body>
<!-- 页面内容 -->
<script src="example.js"></script>
<script></script>
</body>
</html>
1.2 行内脚本和外部脚本的区别
1.2.1 行内脚本
直接将js
代码写到html
文件中;(不推荐)
1.2.2 外部脚本
通过 script
标签,通过外链的形式引入;(推荐)
1.3 js不可用时,如何保证用户体验
在浏览器不支持脚本运行,或者浏览器对脚本的支持被关闭时,可以使用 <noscript>
元素,<noscript>
元素可以包含任何可以出现在 中的HTML元素,<script>
除外;
2 语言基础
2.1 typeof 操作符
typeof操作符是用来判断数据类型的;
undefined:未定义
boolean:布尔值
string:字符串
number:数值
object:对象(不包括函数)或者 null
function:函数
symbol:符号
typeof null = 'object'
2.2 位操作符
2.2.1 什么是位?
“位”指的是操作内存中表示数据的比特(位)
2.2.2 位表示的方式
位表示的方式:以32位的整数表示,即使用32个比特位来表示一个整数。
2.2.3 按位操作
1、 按位非(将所有的0变为1,将所有的1变为0)
2、 按位与
3、按位或
4、按位异或
5、左移
6、无符号右移
7、有符号右移
- 对于正数,有符号右移会将二进制表示向右移动指定数量的位,并在左侧用零填充。
- 对于负数,有符号右移会将二进制表示向右移动指定数量的位,并在左侧用一填充。
- 无符号右移会将二进制表示向右移动指定数量的位,并在左侧用零填充,无论该值是正数还是负数。
2.3 with 语句(已弃用)
3 变量、作用域、内存
变量:基本数据类型(数据存储在栈内存中)、引用数据类型(栈内存存储引用地址、堆内存存储数据)
作用域:理解执行上下文
内存:理解垃圾回收
- 引用计数
对每个值都记录被引用的次数;声明变量并给它赋一个引用值时,这个值的引用数为1;同一个值又被赋给另外一个变量,则引用数加1;
保存对该值引用的变量被其他值覆盖了,那么引用数减1; 一个值的引用数为0,则该值占用的内存将被回收;
循环引用会造成内存泄漏
- 标记清理(最常用的垃圾回收策略)
当变量进入上下文,内部声明一个变量时,这个变量会被加上存在于上下文中的标记;
垃圾回收程序运行的时候,会标记内存中存储的所有变量;它会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉;此后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了;随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。
4 基本引用类型
- Date
- RegExp
- 原始包装类型:Boolean、Number、String
- 单例内置对象:Global、Math、JSON
eval属于全局函数,可以被任何代码调用,相当于ECMAScript解释器,可以直接使用,无需创建实例。
5 集合引用类型
-
对象:Object
-
数组:Array
-
其他引用类型
- ArrayBuffer
- DataView
- 定型数组
- Set
- WeakSet
- Map
- has(‘xxx’) // 查看map是否有xxx键,返回true/false
- get(‘xxx’) // 查看xxx键对应的值
- size // 查看map键值对数量
- delete(‘xxx’) // 删除xxx键值对
- clear() // 清空Map
- WeakMap
键弱引用;当键对象没有其他引用指向它时,它可能会被垃圾回收;这意味着在进行垃圾回收时,如果某个键没有被其他引用持有,该键值对会自动从
WeakMap
中移除,相关资源也会被释放。因此,它不会影响js的垃圾回收机制。而
Map
不一样,使用Map
存储键值对时,无论什么类型的键被添加到Map
中,它们都会保持强引用。这意味着即使键没有其他引用指向它,它仍然会占用内存,并且不会被垃圾回收。
const map = new Map();
let key = {
name: 'John' };
map.set(key, 'value');
console.log('map', map); // map Map(1) { { name: 'John' } => 'value' }
key = null; // 将 key 设置为 null
// 尽管键 key 没有其他引用指向它了,但它仍然存在于 Map 中
console.log(map.size); // 输出:1
console.log('map', map); // map Map(1) { { name: 'John' } => 'value' }
const weakMap = new WeakMap();
let key = {
name: 'John' };
weakMap.set(key, 'value');
console.log('weakMap', weakMap.get(key)); // weakMap value
key = null; // 将 key 设置为 null
// 键 key 没有被其他引用持有,它会被垃圾回收并从 WeakMap 中删除
console.log(weakMap.has(key)); // 输出:false
console.log('weakMap', weakMap.get(key)); // undefined
6 迭代器与生成器
6.1 迭代器
- 基本概念
按照顺序反复多次执行一段程序,通常会有明确的终止条件
for (let i = 0; i < 10; i++) {
console.log('i', i);
}
- 迭代器模式
可迭代对象:实现了正式的Iterable
接口,而且可以通过迭代器Iterator
消费
let arr = ['foo', 'bar'];
console.log('arr[Symbol.iterator]', arr[Symbol.iterator]); // [Function: values]
let iter = arr[Symbol.iterator]();
console.log('iter', iter); // Object [Array Iterator] {}
console.log('1:iter.next()===>', iter.next()); // { value: 'foo', done: false }
console.log('2:iter.next()===>', iter.next()); // { value: 'bar', done: false }
console.log('3:iter.next()===>', iter.next()); // { value: undefined, done: true }
console.log('4:iter.next()===>', iter.next()); // { value: undefined, done: true }
6.2 生成器
- 生成器概念
let generatorFn = function* () {
};
console.log(generatorFn); // [GeneratorFunction: generatorFn]
const g = generatorFn();
console.log(g); // Object [Generator] {}
console.log(g.next); // [Function: next]
- yield
function* generatorFn() {
yield 'foo';
yield 'bar';
return 'baz';
};
let generatorObject = generatorFn();
console.log(generatorObject.next()); // { value: 'foo', done: false }
console.log(generatorObject.next()); // { value: 'bar', done: false }
console.log(generatorObject.next()); // { value: 'baz', done: true }
console.log(generatorObject.next()); // { value: undefined, done: true }
7 对象、类、面向对象编程
7.1 对象
7.1.1 对象的创建过程
-
工厂模式
-
构造函数模式
-
原型模式
-
对象迭代
7.2 JS继承
- 原型链
- 组合继承
- 原型式继承
- 寄生式继承
- 寄生式组合继承
7.3 js中的类
8 代理与反射
8.1 代理 proxy
- 目标对象的抽象
- target:目标对象;
- proxy:代理对象;
- handler:捕获器;
- 捕获器
- trapTarget:目标对象;
- property:属性;
- receiver:代理对象;