js
引用文件可以放在两个位置,一种是html中的head
中,一种是html中的body
中;放置在这两个位置,有何区别呢?
元素的方式引用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>Documenttitle>
<style>style>
<script src="example.js">script>
head>
<body>
<script>script>
body>
html>
引用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>Documenttitle>
<style>style>
head>
<body>
<script src="example.js">script>
<script>script>
body>
html>
直接将js
代码写到html
文件中;(不推荐)
通过 script
标签,通过外链的形式引入;(推荐)
在浏览器不支持脚本运行,或者浏览器对脚本的支持被关闭时,可以使用 元素,
元素可以包含任何可以出现在 中的HTML元素,
除外;
typeof操作符是用来判断数据类型的;
undefined:未定义
boolean:布尔值
string:字符串
number:数值
object:对象(不包括函数)或者 null
function:函数
symbol:符号
typeof null = 'object'
“位”指的是操作内存中表示数据的比特(位)
位表示的方式:以32位的整数表示,即使用32个比特位来表示一个整数。
1、 按位非(将所有的0变为1,将所有的1变为0)
2、 按位与
3、按位或
4、按位异或
5、左移
6、无符号右移
7、有符号右移
变量:基本数据类型(数据存储在栈内存中)、引用数据类型(栈内存存储引用地址、堆内存存储数据)
作用域:理解执行上下文
内存:理解垃圾回收
对每个值都记录被引用的次数;声明变量并给它赋一个引用值时,这个值的引用数为1;同一个值又被赋给另外一个变量,则引用数加1;
保存对该值引用的变量被其他值覆盖了,那么引用数减1; 一个值的引用数为0,则该值占用的内存将被回收;
当变量进入上下文,内部声明一个变量时,这个变量会被加上存在于上下文中的标记;
垃圾回收程序运行的时候,会标记内存中存储的所有变量;它会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉;此后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了;随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。
eval属于全局函数,可以被任何代码调用,相当于ECMAScript解释器,可以直接使用,无需创建实例。
对象:Object
数组:Array
其他引用类型
键弱引用;当键对象没有其他引用指向它时,它可能会被垃圾回收;这意味着在进行垃圾回收时,如果某个键没有被其他引用持有,该键值对会自动从
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
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 }
let generatorFn = function* () {};
console.log(generatorFn); // [GeneratorFunction: generatorFn]
const g = generatorFn();
console.log(g); // Object [Generator] {}
console.log(g.next); // [Function: next]
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 }