JS语法
一、JS介绍
1、js概念
javascript是脚本语言,浏览器会有一个js解释器,对js代码逐行进行解释后执行
https://www.bilibili.com/video/BV1Sy4y1C7ha?p=271&vd_source=501c3f3a75e1512aa5b62c6a10d1550c
ES6语法:
2、js组成
js由三部分组成,如下三部分
- ECMAScript: javascript语法,规定了js的编程语法和基础核心知识,是所有浏览器需要保持的一个标准
- DOM:页面文档对象模型
- BOM:浏览器对象模型,控制浏览器的行为,弹出弹窗、打开页面等等、
3、js的位置
有三种写法,详细看代码,分为行内、内嵌、外部js
注意:外部js的两个
script
标签之间不可以写内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>day2</title>
<script>
// 内嵌式js
alert('内嵌式js')
</script>
</head>
<body>
<!-- 行内式js -->
<input type="button" value="点我" onclick="alert('点我了')">
</body>
<!-- 外链式 -->
<script src="index.js"></script>
</html>
4、js注释
1 | 单行注释: |
5、js输入输出
alert(‘msg’): 浏览器的弹出框
console.log(‘msg’): 控制台打印输出
prompt(‘msg’): 浏览器提示输入
二、数据类型
1、变量
声明变量:
var age;
var
是js
的一个关键字,用来声明变量(variable
变量的意思),使用这个关键字,会自动分配内存空间变量初始化:先声明再赋值
1 | var age; |
变量只声明不赋值:返回结果是
undefined
,表示没有给值,是未定义的变量
1 | var age; |
- 变量不声明不赋值直接使用会报错
1 | console.log(tr); // 提示 tr没有被定义的报错 |
- 变量直接赋值使用不声明,可以使用,不过不推荐该方法,应该要用关键字
var
来声明变量
1 | qq = 123; |
- 更新变量
1 | var age; |
- 变量交换值
1 | var tmp; // 临时变量 |
2、数据类型
js的数据类型是在程序运行时自动判断的,也就是自动推导数据类型
js数据类型分类:
- 简单数据类型:
Number
、String
、Boolean
、Null
、Undefined
- 复杂数据类型:
Object
2.1 数值型number
包含整型和浮点型,默认值是
0
1 | var num = 10; |
1 | // 下面内容作为了解 |
1 | // isNaN(variable) 这个方法用来判断非数字,并且返回一个值,如果是数字,返回false,不是数字,返回的是true |
2.2 布尔类型boolean
布尔类型,结果为
true
、false
对应数字1
和0
,可以用来加法运算
1 | // true 表示真 |
2.3 字符串型String
字符串类型,需要带引号
\n
表示换行
1 | var str = '这是一个字符串\n变量' |
1 | // 字符串的长度 |
1 | // 字符串的拼接 |
2.4 undefined
var age;
只声明变量不赋值,就是未定义类型,此时age
的值是undefined
1 | var age; |
2.5 null类型
var age=null;
声明变量是一个空值,默认值是null
1 | var age = null; |
2.6 检测数据类型
1 | var age = 10; |
3、数据类型转换
3.1 转换为字符型
age.toString()
不常用
String(age)
不常用
+
号拼接,数字加一个空字符串,就可以变为字符串类型(常用)
1 | // toString() 不常用 |
3.2 转换为数字
parseInt(string)
转换为整数型
1 | // parseInt(string) 转换为整数型,得到的是一个整数 |
parseFloat(string)
转换为浮点型
1 | // parseFloat(string) 转换为浮点型,得到的是一个整数 |
- 隐式转换为数字,支持
-
、*
、/
1 | var age = '12'; |
3.3 转换为布尔类型
1 | console.log(Boolean('')); // false |
4、运算符
4.1 算术运算符
就是
加
、减
、乘
、除
、取余
、浮点数
1 | // 加 |
4.2 表达式和返回值
1 | // 1+1 是表达式,1+1 的结果是2 2是返回值 |
4.3 前置递增运算符
格式:
++num
定义: 让一个变量自己
+1
概念:
++num
在运算时,先加1
,再返回值
1 | // 原始变量自己+1 |
4.3 后置递增运算符(常用)
格式:
num++
定义: 让一个变量自己
+1
概念:
num++
在运算时,先返回num
原值,再+1
需要注意: 当
num++
单独使用时,返回值和num++
效果一样,不单独使用时,num++返回的是
num`这个变量的原值
1 | var num = 10; |
4.4 比较运算符
大于:
>
小于:
>
大于等于:
>=
小于等于:
<=
等于2个等于号:
==
,默认会进行数据类型转换,会把字符串类型转换为数字型不等于:
!=
全等:
===
,两个比较的值和数据类型一样,才是true
1 | // 大于 > |
4.5 逻辑运算符
逻辑与:代码符号
&&
,表示and的意思逻辑或:代码符号
||
,表示or的意思逻辑非:代码符号
!
,表示not的意思
1 | // 逻辑与:代码符号 && ,表示and的意思,两侧都为true,结果才是true,只要有一侧为false,结果为false |
- 逻辑与运算符号的中断/短路逻辑
原理:当有多个表达值时,左边的表达式值可以确定结果时,就不需要计算右边的表达式
1 | // 因为是中断,所以逻辑运算符后面的不再进行计算 |
- 逻辑或运算符号的中断/短路逻辑
原理:当有多个表达值时,左边的表达式值可以确定结果时,则返回左边的表达式
1 | // 因为是中断,所以逻辑运算符后面的不再进行计算 |
4.6 赋值运算符
直接赋值:
=
加减一个数后再赋值:
+=
、-=
乘除取模后再赋值:
*=
、/=
、%=
1 | // 赋值运算符 |
4.7 运算符优先级
优先级 运算符解释 符号
1 小括号:
()
2 一元运算符
++
--
!
3 算数运算符 先
*
/
%
后+
-
4 比较运算符
>
>=
<=
5 相等运算符
==
!=
===
!==
6 逻辑运算符 条件表示式有
&&
和||
先计算&&
再计算||
7 赋值运算符
=
8 逗号运算符
,
三、流程控制
分支流程控制和其他编程语言相同,不做过多介绍,只记录语法
1、if-else分支
1 | // if 格式,条件表达式为true,执行if判断里的语句代码,条件表达式为false,则执行else代码 |
- 案例:判断闰年
1 | var year = 2013; |
2、if-else if -else 语句
这个是多条件语句
else if
是需要跟一个条件表达式的
1 | var year = 88; |
3、三元表达式
用来做一些简单的
if-else
判断格式: 条件表示式 ? 表达式1 : 表达式2
解释:条件表达式为真,则返回表达式1的值,如果条件表达式为假,则返回表达式2的值
1 | var sum = 10; |
4、switch语句
解释:多个值来匹配
case
语法格式:
1
2
3
4
5
6
7
8
9
10
11
12 switch (表达式) {
case va1ue1:
statement;
break;
case va1ue2:
statement;
break;
...
default:
statement;
break;
}
switch
语法注意事项:
switch
语句里的表达式是一个准确的值,经常是一个变量- 与
case
后面的值匹配时是全等匹配,既需要判断值是否相等,还要看数据类型是否相等
1 | var num = 9; |
switch
和if - else
的区别switch
语句处理case
比较确定的情况,if else
更灵活,用于处理判断(大于、小于等判断条件)switch
语句进行条件判断后直接执行程序的语句,效率高,if else
语句条件的判断条件比较多,需要不断进行匹配switch
语句适用于分支比较多的情况,if-else
适用于分支较少的情况
5、循环语句
5.1 for 循环
for
循环语句格式for循环的里条件表达式条件走完以后,就会退出循环
1 | for (var i = 0; i <= 10; i++){ |
- 求1…100的整数和
1 | var sum = 0; |
- 求1…100的所有数的平均值
1 | var sum = 0; |
- 求1..100的奇数和偶数的和
1 | // odd是奇数,even是偶数 |
- 求1…100的能被3整除的数字之和
1 | // odd是奇数,even是偶数 |
- for循环求学生成绩总数和平均成绩
1 | // for循环求学生成绩总数和平均成绩 |
- 画星星
1 | // 小星星的个数 |
5.2 for嵌套循环
- 语法格式:
1
2
3
4
5 for (外层初始化变量; 外层的条件表达式; 外层的操作表达式) {
for (里层初始化变量; 里层的条件表达式; 里层的操作表达式) {
statement;
}
}
- 循环嵌套:
- 外层循环执行一次,里层循环全部执行一次
1 | for (var i = 0; i <= 4; i++){ |
- 打印五行五列玫瑰花
需要定义一个空字符串变量来接收输出的玫瑰花
这个五行五列可以写活了,使用变量代替接收需要打印多少行多少列
1 | var exper = ''; |
- 9X9乘法口诀
1 | var exper = ''; |
- 打印倒三角
1 | var exper = ''; |
5.3 while循环
while 循环,条件表达式为true,则执行循环,否则退出循环
语法格式:
1
2
3 while (条件表达式) {
代码语句;
}
1 | var num = 0; |
5.4 do while循环
do...while
是while
循环的变体,执行循环前先自己执行一次代码,然后对while
中的条件判断语句判断,如果为true
,则继续执行while
循环,如果为false
,则退出循环语法格式:
1
2
3 do {
statement;
}while (条件表达式);
do...while
语句会至少执行一次循环代码,再进行while
的条件判断循环
1 | var num = 3; |
5.5 break关键字
break
用于退出循环
1 |
|
5.6 continue关键字
continue
跳出本次循环
1 | for (var i = 0; i < 3; i++){ |
四、数组
1、数组创建
- 两种方式:
- 利用
new
创建数组,学习面向对象再使用- 利用数组字面量创建数组,字面量意思是看到符号就可以知道是什么意思,数组字面量是符号
[]
- 数组特点:
- 数组元素可以是任意类型,但是需要以
逗号
隔开
1 | // 创建了一个空数组 |
2、访问元素
- 格式:
1 数组名[索引值]
- 索引值从
0
开始,访问超过索引值的元素,结果是undefined
,因为数组元素不存在,访问就是undefined
1 | // 访问元素使用 nameArr[索引号],索引号从0开始 |
3、遍历数组
使用
for
循环遍历数组获取数组的长度:
Arr.length
1 | // 创建了一个数组 |
- 求数组的总和与平均值
1 | // |
- 求数组元素的最大值
1 | var numArr = [1, 2, 99, 35, 3, 4]; |
- 数组元素变为字符串用分隔符连接
1 | var numArr = [1, 2, 99, 35, 3, 4]; |
4、数组新增元素
- 可通过修改数组的length属性来进行数组扩容
- length属性是可以读写的,写的权限意思就是可以手动再进行赋值
- 对数组继续使用索引赋值
- 数组元素的个数为3,想要新增元素,就可以从索引值4开始对数组进行新增赋值
4.1 修改数组的length属性
1 | var numArr = [1, 2, 3, 4]; |
4.2 修改索引号赋值
1 | var naArr = ['red', 'green', 'blue']; |
4.3 筛选数组的元素
1 | // 筛选出大于等于3的元素 |
4.4 反转数组元素
1 | // 数组翻转 |
五、函数
1、函数格式
函数格式:
1
2
3 function 函数名() {
// 函数体
}函数是做某件事情
切记:函数只声明不调用是不会被执行的
1 | // 函数定义 |
- 函数求
1-100
的和
1 | // 函数定义 |
2、函数的参数
- 函数参数的形式
js
中函数不传值,默认的参数值时undefined
1
2
3
4
5 function 函数名(形参1, 形参2...) {
函数体;
}
- 函数参数的调用时规则,可以看出js的函数很不严谨,会出现形参和实参个数不匹配的问题
- 调用函数传入的参数个数和函数定义时一致,正常输出
- 调用函数传入的参数个数大于函数定义时的参数个数,会把多余传入的丢弃掉
- 调用函数不传入的参数,函数里面的形参会变为
undefined
1 | // 函数的参数 |
- 函数的例子
1 | // 函数的参数 |
3、函数的返回值
return
关键字是函数返回值return
可以接受三元运算符return
表示函数被终止,遇到return
后面的代码不会再被执行return
只能返回一个值,有多个值以逗号隔开页只是以最后一个为准,不过我们可以把n
个结果值包在一个数组里返回也可以- 如果函数没有
return
关键字,则返回undefined
值
1 | // 函数的参数 |
4、可变长参数arguments
当我们不知道要传入的参数有多少个时,可以用
arguments
获取到所有函数都有一个
arguments
属性,用来获取所有传入的参数,和python
的args
/kwargs
作用一样
arguments
是一个伪数组- 伪数组
- 不是真正的数组
- 有
length
属性- 按索引的方式存储
- 但是没有数组的
push()
、pop()
等方法
1 | // 函数的参数 |
- 求任意个数的最大值
1 | function getMax() { |
- 函数反转任意数组
1 | function reverse(arr) { |
5、函数相互调用
切记:函数只声明不调用是不会被执行的
1 | function foo(){ |
6、函数声明方式
方式一
利用函数关键字定义,也叫命名函数
```js
function 函数名() {
// 函数体
}
1
2
3
4
5
6
7
8
9
- 方式二
- 函数表达式(匿名函数)
- ```js
var 变量名 = function() {
// 函数体
}
- 匿名函数
1 | var fu = function (name) { |
7、作用域
就是代码变量在某个范围内起作用和效果,提高程序可靠和减少命名冲突
js的作用域(
es6
之前,我们现在学的是es5
语法):全局作用域和局部作用域全局作用域
整个
script
标签,或者一个单独的js
文件
1 var num = 10;局部作用域
在函数内部的就是局部作用域,只在函数内部起作用
1
2
3 function fn() {
// 局部作用域
}
8、变量作用域
根据作用域不同把变量分为全局变量和局部变量
全局变量
- 在全局作用下任何位置都可以用的变量,也就是函数外部的变量
- 全局变量在函数内部也可以使用
- 如果在函数内部直接赋值没有声明的变量也叫全局变量,声明变量不带
var
- 只有浏览器关闭才会被销毁,比较占内存
1
2
3
4
5
6
7
8var num = 10;
console.log(num); // 10
function fn() {
console.log(num);
}
fn(); // 10局部变量
- 在局部作用域的变量,也就是在函数内部的变量叫局部变量,形参也是局部变量
- 但是要注意,如果函数内部声明变量时没有带
var
关键字,就会变为全局变量 - 在函数内部,所在的代码块被执行了,会被初始化,代码块运行结束后,会被销毁,节省内存空间
1
2
3
4
5
6
7
8
9
10
11
12
13function fn() {
var num_t = 10;
num_q = 30;
}
fn();
// 如果在函数外部引用函数里定义的局部变量,会报引用错误
// ReferenceError: num_t is not defined
console.log(num_t);
// 下面的num_q正常输出为30
console.log(num_q); // 30
9、块级作用域
js
中没有块级作用域,js
的作用域只有全局和局部
js
在es6
语法的时候会新增作用域块级作用域:
{}
、if {}
、for {}
也就是说
js
在块级作用域外面也能访问块级作用域内部的变量
10、作用域链
内部函数访问外部函数的变量,使用链式查找来决定取值,称为就近原则
1 | var num = 10; |
六、代码预解析
1、预解析
js
引擎运行js
代码分为两步
- 一是预解析
- 表示
js
引擎会把js里所有的var
、function
提升到当前作用域- 分为变量预解析、函数预解析
- 二是代码执行
- 按照代码书写的顺序从上往下依次执行
1.1 变量预解析
把所有变量声明提升到当前作用域最前面,不提升赋值操作
1 | console.log(num); // undefined |
1 | fu(); // 输出报错: TypeError: fu is not a function |
1.2 函数预解析
把所有函数声明提升到当前作用域最前面,不调用函数
1 | foo(); |
这样定义函数预解析会出现错误
因为匿名函数的调用必须放在函数定义的下面
1 | // 等价于如下代码 |
七、对象
1、对象定义
js
中对象时一组无序的相关属性和方法的集合,例如字符串、数字、数组等等属性:特征
方法:行为
js
中的对象和python
的字典类似,也是一个键值对的数据类型
2、创建对象: 字面量
创建对象有三种方式
- 字面量,也就是花括号
{}
就表示是个对象
2.1 字面量创建对象
格式:
var objs = {}
1 | function fo (){ |
2.2 调用对象的属性
- 两种调用方式
- 使用点的方式,格式:
obj.name
- 使用中括号,格式:
obj['name']
和python的字典取值一样
1 | function fo (){ |
3、创建对象: new object
利用等号赋值的方式来进行填充数据
可以用点号或中括号来填充数据
1 | function fo() { |
4、创建对象:构造函数
构造函数创建对象的原因:
- 上面两种方式只能依次创建一个对象,所以需要使用构造函数创建对象,类比python的面向对象编程,将创建对象里重复的动作抽离出来,变成一个模板来创建多个对象来使用
- 利用函数创建对象,可以把重复的部分抽离出来,那这个函数就是构造函数
- 但是这个函数不一样,里面封装的不是普通代码,而是对象
构造函数定义:
- 将对象里面一些相同的属性和方法抽象出来封装到函数里面
格式:
1
2
3
4
5
6
7
8
9
10 // 创建构造函数
function 构造函数(){
this.属性 = 值;
this.方法 = function (){
// code;
}
}
// 调用构造函数
new 构造函数();
- 构造函数和普通函数在定义没区别
- 构造函数里的
this
表示指向当前创建的空对象,和python
里面向对象的self
一个意思,表示当前创建的对象本身- 调用时使用
new
关键字来调用声明- 相当于
python
面向对象的_ _init_ _
方法构造函数的规范:
- 函数名首字母要大写
- 构造函数不需要
return
就可以返回值- 构造函数返回对象时,会把构造函数名也返回,如下面代码里的
Star { name: 'sam', age: 20, sex: 'man' }
new Star()
就表示创建了一个对象
1 | function Star(name, age, sex) { |
4.1 new执行时会做的什么?
- 在内存中创建一个空对象
- 让
this
指向这个新的对象- 执行构造函数的代码,给这个对象添加属性和方法
- 返回这个对象,注:构造函数不需要
return
5、遍历对象
for...in
用来遍历对象或数组,常用来遍历对象语法格式:
1
2
3
4 var obj = {'name':'sam', 'age':18};
for (var k in obj){
console.log(obj[k]);
}
- 注意:
var k
输出的是对象的名,也就是键
- 在
for..in
里面,输出值,必须使用中括号方法[]
,如果使用点.
会输出为undefined
1 | var obj = { |
6、内置对象Math
网址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math
Math
是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math
不是一个函数对象。
1 | // Math 取圆周率 |
6.1 封装自己Math对象
1 | // 封装自己的Math对象 |
6.2 Math取绝对值
1 | // 取绝对值 |
6.3 向下取整
往小了取值
floor
:地板的意思,也就是在我们脚下,所以是取小值
1 | // 向下取整,取小数数值的最小值,也就是整数部分 |
6.4 向上取整
往大了取值
ceil
:天花板的意思,也就是在我们头上,也就是取大的值
1 | // 向上取整,相当于四舍五入的五入, |
6.5 四舍五入
1 | // 四舍五入,其他数字都是四舍五入,但是.5比较特殊,是往大了取 |
6.6 随机数
Math.random()
- 取值范围是:
[0,1)
,取值范围在0
到1
之间的小数,可以取到0
random()
函数里面不跟参数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/random
1 | // 得到一个两数之间的随机整数,包括两个数在内 |
1 | // 随机取一个数组的值 |
- 猜数字
需要在html页面中看到效果
1 | <script> |
7、Date对象
1 | // Date里面不跟参数,返回的是当前时间 |
7.1 年月日
1 | // 格式化年月日 |
7.2 时分秒
1 | // 格式化 时 分 秒 |
八、ES6语法
ES6语法是在原有JavaScript的语法基础上,进行了加强和优化,所以需要学习下
目前ES6语法中的面向对象编程在前端的应用场景比较少,所以ES6涉及到面向对象的地方可以先跳过,学习使用函数式编程就可以满足平时的日常开发,因为vue中也有大量应用到了ES6语法
黑马程序员ES6语法
尚硅谷es6语法
https://www.bilibili.com/video/BV1uK411H7on?p=44&vd_source=501c3f3a75e1512aa5b62c6a10d1550c
javascript, es6, nodejs, commonJS的区别和联系
这几个概念如果没有仔细读相应的教程或者文档,很容易混淆
这四者的关系是什么?
- ES6,是javascript语言规范,用于规范javascript, 也就是定义javascript语法标准。
- Node.js 是javascript运行时环境(javascript runtime),主要作用就是可以让javascript脱离浏览器执行。
- commonJS是一个在2014年已经被终止的项目,它的规范让javascript可以实现模块化。Node.js最开始就只支持commonJS的模块化标准,即 require/exports, 后来ES6改进了模块化标准为用 import/export, 相对前者有更多灵活的用法。
- 所以为了让javascript更好的被使用,这三者才会出现, 当然实现ES6标准的不止javascript,还有其他语言,如JScript,ActionScript等脚本语言都是基于ECMAScript标准实现的。
- 很多人弄不清楚Node.js到底是不是javascript?
- 不是,javascript是语言,Node.js是javavscript的运行时。
- Node.js 等于 chrome浏览器的V8引擎+一些javascript运行时库。
Node.js 的出现要解决什么问题?
- Node.js的出现是为了能让javascript脱离浏览器执行。这样javascript就可以操作除了前端功能(DOM)之外的东西–后端服务
- javascript诞生之初的目的是用在web, 由浏览器执行。那么脱离浏览器,javascript就不能执行了吗? nodejs出现之前,确实是这样的。因为只有浏览器里才有javascript解释器!只有它才知道javascript要怎么执行。既然如此,只要把这个解释器拿出来,再添加一些必要的执行库工具不就可以让javascript脱离浏览器执行了嘛,所以nodejs就诞生了。各家浏览器商都有自己的javascript解释器, nodejs用的是chrome的V8 javascript引擎
Node.js(V8)和ES6的关系?
Node.js用V8引擎,而V8如果能解析ES6规范的javascript语法,那么Node.js也就能支持相应的语法标准。
ECMA每发布一个标准,各大浏览器的javascript引擎都会尽量跟上,它们现在大部分都支持了ES5,ES6 还没有被完全支持。而V8对ES6已经高度支持了,也就是说Node.js对ES6也高度支持。
其他的区别文章:https://blog.csdn.net/m0_48076809/article/details/106888814
语言标准 | 语言 | javascript runtime | 模块生态系统项目 |
---|---|---|---|
ECMAScript6 | javascript | Node.js | CommonJS |
1、标识符
1.1 let
1.2 const
九、Promise教程
尚硅谷promise教程
十、axios
尚硅谷axios
注意在vue中使用axios时,then里面的回调函数一定要使用箭头函数,不能使用匿名函数,会导致用this取vue的数据源时,this不会指向vm
http://www.zzvips.com/article/195973.html
匿名函数的指针指向->函数操作的本身
箭头函数的指针指向->组件
十一、node
黑马程序员node
https://www.bilibili.com/video/BV1a34y167AZ?p=3&vd_source=501c3f3a75e1512aa5b62c6a10d1550c