【笔记】JS学习笔记

前言

JavaScript(通常缩写为JS)是一种高级的、解释型的编程语言。JavaScript是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持I/O,比如网络、存储和图形等,但这些都可以由它的宿主环境提供支持。它已经由ECMA(欧洲电脑制造商协会)通过ECMAScript实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器(Chrome、IE、Firefox、Safari、Opera)支持。(维基百科

JS的根据ECMA定义的语法学习笔记

1994年,网景公司(Netscape)发布了Navigator浏览器的0.9版
1995年,网景公司招募了程序员Brendan Eich预期使用Scheme语言作为网页的脚本语言
1995年,Sun公司将Osk语言更名为Java语言,网景公司管理层也想将Java语言作为网页的脚本语言
但是Brendan Eich对Java语言并不感兴趣,于是用10天的时间创造了Mocha(摩卡)语言
网景公司在发布2.0beta版的Navigator浏览器时,将Mocha更名为LiveScript
网景公司在发布2.0beta3版的Navigator浏览器时,将LiveScript更名为JavaScript
1995年,微软公司推出InternetExplorer浏览器,微软对Navigator浏览器进行了逆向工程,创造了JScript
1996年11月,网景公司正式向ECMA(欧洲计算机制造商协会)提交语言标准
1997年6月,ECMA以JavaScript语言为基础制定了ECMA-262标准规范,ECMA-262标准规范定义了ECMAScript规范
JavaScript是ECMAScript的一种实现,ActionScript和JScript也都是ECMAScript的实现

JS的使用方式

内联JS

  • 事件触发时会执行JS代码
1
<div onclick="console.log();"></div>
  • 超链接点击时会执行JS代码
1
<a href="javascript: console.log();"></a>

内部JS

  • <script>引入JS文件时会阻塞HTML解析
1
2
3
<script>
console.log();
</script>

外部JS

定义JS文件

index.js
1
console.log();

HTML文件中引入JS文件

  • <script>引入JS文件时会阻塞HTML解析

type="":脚本类型

text/javascript:JavaScript脚本

1
<script src="index.js" type="text/javascript"></script>
安全校验

integrity="":校验JavaScript文件,校验失败不会加载
crossorigin="":请求JavaScript文件时是否携带用户凭证(Cookie、SSL证书)

anonymous:缺省值,不携带凭证
use-credentials:携带凭证

1
<script src="index.js" type="text/javascript" integrity="sha256-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" crossorigin="anonymous"></script>
不阻塞HTML渲染
defer
  • 不阻塞HTML渲染,异步下载JS文件
  • HTML完全渲染后,按顺序执行JS文件
1
<script src="index.js" type="text/javascript" defer></script>
async
  • 不阻塞HTML渲染,异步下载JS文件
  • 完全异步下载和执行JS文件,JS执行时无法保证与其他JS文件之间的执行顺序,也无法保证HTML已渲染完成
1
<script src="index.js" type="text/javascript" async></script>

不支持JS时的友好提示

  • <noscript></noscript>的内容只有在浏览器不支持JS渲染(浏览器关闭了JS渲染引擎)时才会执行
  • <noscript>不会阻塞HTML解析
1
2
3
<noscript>
...
</noscript>

注释

单行注释

1
// 单行注释

多行注释

1
/* 多行注释 */

文档注释

@param:用于描述函数的参数
@returns:用于描述函数的返回值
@description:用于描述代码的功能
@throws:用于描述可能抛出的异常
@example:用于提供使用示例
@class:用于描述类
@method:用于描述类中的方法
@property:用于描述类的属性

1
2
3
4
5
6
7
8
9
10
/**
* 函数名
* @param {string} name 姓名
* @param {number} age 年龄
* @returns {string} 返回姓名和年龄
* @description 函数功能描述
*/
function 函数名(name, age) {
return name + age;
}

输出语句

弹窗

1
alert(变量名);
1
window.alert(变量名);

输出到控制台

1
console.log(变量名);

输出对象结构

1
console.dir(变量名);

输出到DOM

1
document.write(变量名);

输入语句

弹窗接收字符串

1
var str = prompt();
1
var str = prompt("提示文字");

弹窗接收布尔值

1
var str = confirm();
1
var str = confirm("提示文字");

定义变量

  • JS中的变量都是保存到栈内存中的

    • 基本类型数据是保存到栈内存中的,值与值之间是独立存在,修改一个变量不会影响其他的变量
    • 对象类型数据是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是用一个对象的引用,当一个通过一个变量修改属性时,另一个也会受到影响
  • 当比较两个基本类型数据时,是比较的值。当比较两个引用类型数据时,是比较的对象的内存地址

  • 使用var定义变量时,最终会成为全局变量window的属性

var(ES5)

  • 定义没有作用域的变量
1
var 变量名 = 值;
1
var 变量名1 = 值, 变量名2 = 值;

let(ES6)

  • 定义具有作用域的变量
1
let 变量名 = 值;
1
let 变量名1 = 值, 变量名2 = 值;

const(ES6)

  • 定义具有作用域的常量
1
const 变量名 = 值;
1
const 变量名1 = 值, 变量名2 = 值;

数据类型

  • 基本数据类型

    • string
    • number
    • boolean
    • undefined
  • 引用数据类型

    • function
    • object
1
var result = typeof(变量名);

number数值型

  • 在JS中所有的数值都是number类型,包括整数和浮点数
  • 在JS中整数的运算基本可以保证精确,如果使用JS进行浮点运算,可能得到一个不精确的结果,所以千万不要使用JS进行对精确度要求比较高的运算
1
var value = 1;
1
var value = 0.1;
  • 语法糖:利用_分隔数字,可以提高代码的可读性,不限制_书写的位置(ES6)

英式数字分隔法

1
var oneBillion = 1_000_000_000;

中式数字分隔法

1
var oneBillion = 10_0000_0000;

其他进制

  • 描述二进制的数值,需要以0b开头
1
var value = 0b1;
  • 描述八进制的数值,需要以0开头
1
var value = 01;
  • 描述十六进制的数值,需要以0x开头
1
var value = 0x1;

最大值

  • 如果使用Number表示的数字超过了最大值,则会返回一个Infinity (表示正无穷)
1
var value = Number.MAX_VALUE

最小值

  • 如果使用Number表示的数字低于了最小值,则会返回一个-Infinity (表示负无穷)
1
var value = Number.MIN_VALUE

string字符串

  • 在JS中字符串需要使用引号引起来
  • 使用双引号或单引号都可以,但是不能混着用
1
var value = "字符串";

boolean布尔型

  • 布尔值只有两个,主要用来做逻辑判断
  • true表示真,false表示假
1
var value = true
1
var value = false

undefined类型

  • undefined类型只有一个值,就是undefined
  • 当声明一个变量,但是并不给变量赋值时,它的值就是undefined
1
var value = undefined

object对象类型

  • 对象中没定义任何字段时值为null
1
var value = {}
1
var value = null

检查数据类型

typeof操作符

  • 通过typeof操作符检查当前数据的数据类型

  • 使用typeof检查字符串值时,会返回string

  • 使用typeof检查数值时,会返回number

    • 使用typeof检查Infinity值时,也会返回number
  • 使用typeof检查布尔值时,会返回boolean

  • 使用typeof检查一个不存在的变量只声明但没定义的变量时,会返回undefined

    • 使用typeof检查undefined值时,也会返回undefined
  • 使用typeof检查一个对象时,会返回object

    • 使用typeof检查null值时,也会返回object
    • 使用typeof检查一个函数时,虽然函数也是对象,但不会返回object,而是返回function,因为函数是特殊的对象
1
var result = typeof 被检测的数据;

检查是否是number数值型

1
var result = isNaN(<value>);

数据类型转换

隐式数据类型转换

转换为number数值型
利用算数运算符
  • 利用除了+以外的算数运算符进行运算时,会进行隐式数据类型转换,将数据转换为number数值型
1
var result = 被转换的数据 - 0;
1
var result = 被转换的数据 * 1;
1
var result = 被转换的数据 / 1;
1
var result = 被转换的数据 % 被转换的数据;
1
var result = 被转换的数据 ** 1;
利用比较运算符
  • 使用==进行比较运算时,会尝试将双方都转换为number数值型

传送门

转换为string字符串
  • 利用+运算符与字符串相加,就会进行隐式数据类型转换,将数据转换为string字符串
1
var result = 被转换的数据 + "";
转换为boolean布尔型
利用分支语句和条件语句
  • 分支语句和循环语句的条件表达式如果是非布尔型数据,可以自动转换为boolean布尔型

  • 直观上为空的值会转换为false0, NaN,""(空字符串), undefined, null(空对象),其他情况会转换为true

1
if (被转换的数据) {}
1
while (被转换的数据) {}
利用逻辑运算符
  • 通过&&||进行逻辑运算时,从左到右依次将数据转换为boolean布尔型,再进行逻辑运算

传送门

  • 通过!进行逻辑运算时,会自动将数据转换为boolean布尔型,但会得到错误的结果,再次进行一次!运算,才能得到正确的结果
1
!!被转换的数据

显式数据类型转换(强制类型转换)

转换为number数值型
Number()
  • 字符串转换为数值
    • 去除字符串的首尾空字符后
      • 如果剩下的是只包含数字的字符串,则直接将其转化为数字
      • 如果剩下的是空串,则转换为0
      • 如果剩下的字符串中有非数字字符,则转换为NaN
  • 布尔值转换为数值
    • true转换为1
    • false转换为0
  • undefined转换为数值,转换为NaN
  • 对象转换为数值
    • null转换为0
    • 其他情况转换为NaN
1
var result = Number(被转换的数据);
parseInt()和parseFloat()
  • parseInt()函数可以把一个字符串转换为一个整数,也可以将一个字符串中有效的整数内容提取出来
  • 如果parseInt()函数的参数传递的是非字符串数据,会先将其转换为字符串,然后再进行转换
1
var result = parseInt(被转换的数据);
  • parseFloat()函数可以把一个字符串转换为一个浮点数,也可以将一个字符串中有效的浮点数内容提取出来
  • 如果parseFloat()函数的参数传递的是非字符串数据,会先将其转换为字符串,然后再进行转换
1
var result = parseFloat(被转换的数据);
转换为string字符串
String()
  • 调用String()函数,并将被转换的数据作为参数传递给函数
  • 使用String()函数做强制类型转换时,对于number和boolean类型的值实际上就是直接调用的toString()方法,但是对于null和undefined这两个值就不会调用toString()方法,它会将null值转换为字符串”null”,将undefined值转换为字符串”undefined”
1
var result = String(被转换的数据);
toString()
  • 调用被转换数据类型的toString()方法,该方法不会影响到原变量,他会将转换的结果返回
  • null和undefined这两个值没有toString()方法,所以null和undefined不能调用toString()方法,否则会报错
1
var result = 被转换的数据.toString();
转换为boolean布尔型
Boolean()
  • 数值转换为布尔值
    • 0转换为false
    • NaN转换为false
    • 其他情况转换为true
  • 字符串转换为布尔值
    • 空串转换为false
    • 其他情况转换为true
  • undefined转换为布尔值,转换为false
  • 对象转换为布尔值
    • null转换为false
    • 其他情况转换为true
1
var result = Boolean(被转换的数据);

运算符

算术运算符

  • +-*/%**++--

赋值运算符

  • =+=-=*=/=%=

比较运算符

  • ><>=<======!=

  • 通过==进行比较运算时,会尝试将双方都转换为number数值型,再进行逻辑运算返回布尔值

    • null == undefined:返回true
    • NaN == NaNNaN == 0:因为NaN不是数值,所以与任何数值比较都不是相同的,所以无论如何比较都返回false
    • "" == 0"1" == 1:将string字符串转换为number数值型,再进行比较,所以返回true
    • true == 1false == 0,将boolean布尔型转换为number数值型,再进行比较,所以返回true
    • true == "1"false == "",将双方都转换为number数值型,再进行比较,所以返回true
    • 对象类型数据进行比较时,根据Symbol.toPrimitive方法返回的值,进行比较
  • 通过===进行比较运算时,如果双方的数据类型不一致,则直接返回false

1
console.log(null == undefined);
1
2
3
4
5
6
7
var obj = {
[Symbol.toPrimitive]() {
return 0;
}
}

console.log(obj == 0);

逻辑运算符

  • &&(短路与)、||(短路或)、!(非)

逻辑与的本质

  • 通过&&进行逻辑运算时,从左到右依次将数据转换为boolean布尔型,再进行逻辑运算
    • 当遇到的操作数结果为false时,立即终止运算,并返回这个操作数(运算元)的初始值
    • 当遇到的操作数结果全部为true时,返回最后一个操作数的初始值

逻辑与的应用

执行存在的函数
  • 如果前面有属性不存在,则会立即终止,以防止想要执行的函数不存在最终报错
1
2
3
4
5
6
7
var obj = {
key: {
fn: function () {}
}
}

obj && obj.key && obj.key.fn();

逻辑或的本质

  • 通过||进行逻辑运算时,从左到右依次将数据转换为boolean布尔型,再进行逻辑运算
    • 当遇到的操作数结果为true时,立即终止运算,并返回这个操作数(运算元)的初始值
    • 当遇到的操作数结果全部为false时,返回最后一个操作数的初始值

逻辑或的应用

获取第一个有值的数据
  • 如果前面的变量值为空,会继续向下一个操作数寻找值,以尽可能防止得到空值
1
2
3
4
5
var data1 = undefined;
var data2 = undefined;
var data3 = "";

var result = data1 || data2 || data3;

按位运算符

  • &|^~<<>>>>>

赋值运算符

  • &=|=^=<<=>>=>>>=

对象

传送门

数组

  • JS的数组可以存储任意类型的数据
  • JS的数组长度是可以被任意改变的
  • JS的数组实际上也是对象类型数据

传送门

函数

  • 函数中可以封装一些代码,在需要时可以执行这些代码
  • JS的函数实际上也是对象类型数据

传送门

分支语句

if

单重判断

1
2
3
if (布尔表达式) {
布尔表达式成立时执行的代码;
}

双重判断

1
2
3
4
5
if (布尔表达式) {
布尔表达式成立时执行的代码;
} else {
布尔表达式不成立时执行的代码;
}

多重判断

1
2
3
4
5
6
7
if (布尔表达式1) {
布尔表达式1成立时执行的代码;
} else if (布尔表达式2) {
布尔表达式2成立时执行的代码;
} else {
以上布尔表达式都不成立时执行的代码;
}

嵌套判断

1
2
3
4
5
if (布尔表达式1) {
if (布尔表达式2) {
布尔表达式12都成立时执行的代码;
}
}

switch…case

  • JS中的switch语句具有case穿透的特性,需要使用break关键字进行终止操作
  • switch语句采用的是===进行相等判断,所以必须要保持数据类型相同
1
2
3
4
5
6
7
8
9
10
11
switch (变量名) {
case1:
变量值为值1时执行的代码;
break;
case2:
变量值为值2时执行的代码;
break;
default :
变量值不为以上任何值时执行的代码;
break;
}

循环语句

while

1
2
3
while (布尔表达式) {
布尔表达式成立时反复执行的代码;
}

for

1
2
3
for (var i = 起始值; 布尔表达式; i++) {
布尔表达式成立时反复执行的代码;
}

for…in

  • 通常用于遍历对象
    • 遍历对象时,得到的是key
    • 遍历数组时,得到的是无序的元素值
    • 遍历字符串时,得到的是字符下标
1
2
3
for (const key in obj) {
console.log(obj[key]);
}

for…of(ES6)

  • 通常用于遍历数组,只能遍历有迭代器对象的集合
    • 遍历对象时,得到的是value
    • 遍历数组时,得到的是有序的元素值
    • 遍历字符串时,得到的是字符
1
2
3
for (const item of arr) {
console.log(item);
}

三元运算

1
var result = 布尔表达式 ? 布尔表达式成立时返回的结果 : 布尔表达式不成立时返回的结果;

JS的浏览器API

完成

参考文献

知乎——知乎用户
mdn web docs
W3school
segmentfault——Jason
php中文网——coldplay.xixi
稀土掘金——邑大学子_
简书——浅瞳_e42e
CSDN——yunchong_zhao
mozilla
菜鸟笔记
CSDN——昕光xg
哔哩哔哩——前端开发专业教程