语法基础
JS的发展史
ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。在日常场合,这两个词是可以互换的。
JS能干什么
1.前端开发
2.服务端开发 => Node.js
3.桌面应用开发
JS的组成
1. ECMASCRIPT: 定义了javascript的语法规范,描述了语言的基本语法和数据类型
2. BOM (Browser Object Model): 浏览器对象模型
- 有一套成熟的可以操作浏览器的 API,通过 BOM 可以操作浏览器。比如: 弹出框、浏览器跳转、获取分辨率等
3. DOM (Document Object Model): 文档对象模型
- 有一套成熟的可以操作页面元素的 API,通过 DOM 可以操作页面中的元素。比如: 增加个 div,减少个 div,给div 换个位置等
JS代码书写的位置
1.行内式 (不推荐)
2.内嵌式 <script></scrpit> 可以放在head标签或body标签里面
3.外链式 <srcipt src = 'js文件路径'></script> 可以有多个js文件 (推荐)
JS的注释
1.单行注释 // 快捷键 ctrl+/
2.多行注释 /**/ 快捷键(每个编辑器不一样)
变量(重点)
- 变量指的是在程序中保存数据的一个容器
- 变量是计算机内存中存储数据的标识符,根据变量名称可以获取到内存中存储的数据
- 也就是说,我们向内存中存储了一个数据,然后要给这个数据起一个名字,为了是我们以后再次找到他
- 变量的本质是内存中一个存储单元
- 语法: var 变量名 = 值
变量的命名规则和规范
- 规则:必须遵守,不做事就是错
- 变量名有数字,下划线,字母,$ 组成
- 严格区分大小写
- 不能以数组开头
- 不能是关键字或者保留字
- 不能有空格
- 规范:建议遵守,不遵守不会报错
- 变量名尽量语义化
- 驼峰命名法
访问变量 => 控制台输出打印
console.log('打印的内容')
数据类型(重点)
基本数据类型
1.数值类型(number)
- 一切数字都是数值类型
- NaN 非数字
2.字符串类型(string)
- 被引号包裹的所有内容(双引号和单引号)
3.布尔类型(boolean)
- 只有true和flase
4.null类型(null)
- 只有一个null,表示赋了一个为null的值
5.undefinde类型(undefinde)
- 只有一个,表示没有值的意思
复杂数据类型 => 暂时不讲,后面讲
判断一个数据是什么类型的
- 用typeof关键字来判断
例:
var num = 100
console.log(typeof num) //number
数据类型转换
其他类型转数值类型
Number(变量)
- 可以把一个变量强制转换成数值类型
- 可以转换小数,会保留小数
- 可以转换布尔值
- 遇到不可转换的都会返回 NaN
- true - 1
- false- 0
- undefined - NaN
- null - 0
parseInt(变量)- 取整
- 从第一位开始检查,是数字就转换,直到一个不是数字的内容
- 开头就不是数字,那么直接返回 NaN
- 不认识小数点,只能保留整数
parseFloat(变量)
- 从第一位开始检查,是数字就转换,知道一个不是数字的内容
- 开头就不是数字,那么直接返回 NaN
- 认识一次小数点
其他类型转字符串
String(变量)
- 所有数据类型都可以
使用加法运算
- 在 JS 里面,`+` 由两个含义
- 字符串拼接: 只要 `+` 任意一边是字符串,就会进行字符串拼接
- 加法运算:只有 `+` 两边都是数字的时候,才会进行数学运算
其他数据类型转布尔
Boolean(变量)
- 在 js 中,只有 `''`、`0`、`null`、`undefined`、`NaN`,这些是 false,其余都是 true
运算符
数学运算符
1. +
- 只有符号两边都是数字的时候才会进行加法运算
- 只要符号任意一边是字符串类型,就会进行字符串拼接
2. -
- 会执行减法运算
- 会自动把两边都转换成数字进行运算
- 30' - 20会自动转换为 30 - 20
3. *
- 会执行乘法运算
- 会自动把两边都转换成数字进行运算
4. /
- 会执行除法运算
- 会自动把两边都转换成数字进行运算
5. %
- 会执行取余运算
- 会自动把两边都转换成数字进行运算
赋值运算符
=
- 就是把 `=` 右边的赋值给等号左边的变量名
- var num = 100
- 就是把 100 赋值给 num 变量
- 那么 num 变量的值就是 100
2. +=
var a = 10;
a += 10;
console.log(a); //=> 20
- a += 10 等价于 a = a + 10
3. -=
var a = 10;
a -= 10;
console.log(a); //=> 0
- a -= 10 等价于 a = a - 10
*=
```
var a = 10;
a *= 10;
console.log(a); //=> 100
``
- `a *= 10` 等价于 `a = a * 10`
5. /+
```
var a = 10;
a /= 10;
console.log(a); //=> 1
``
- a /= 10 等价于 a = a / 10
6. %=
```
var a = 10;
a %= 10;
console.log(a); //=> 0
- a %= 10 等价于 a = a % 10
比较运算符
==
- 比较符号两边的值是否相等,不管数据类型
- `1 == '1'`
- 两个的值是一样的,所以得到 true
2. ===
- 比较符号两边的值和数据类型是否都相等
- `1 === '1'`
- 两个值虽然一样,但是因为数据类型不一样,所以得到 false
0. !=
- 比较符号两边的值是否不等
- `1 != '1'`
- 因为两边的值是相等的,所以比较他们不等的时候得到 false
0. !==
- 比较符号两边的数据类型和值是否不等
- `1 !== '1'`
- 因为两边的数据类型确实不一样,所以得到 true
0. >=
- 比较左边的值是否 大于或等于 右边的值
- `1 >= 1` true
- `1 >= 0` true
- `1 >= 2` false
0. <=
- 比较左边的值是否 小于或等于 右边的值
- `1 <= 2` true
- `1 <= 1` true
- `1 <= 0` false
0. >
- 比较左边的值是否 大于 右边的值
- `1 > 0` true
- `1 > 1` false
- `1 > 2` false
0. <
- 比较左边的值是否 小于 右边的值
- `1 < 2` true
- `1 < 1` false
- `1 < 0` false
逻辑运算符
&&同为真则为真
- 进行 且 的运算
- 符号左边必须为 true 并且右边也是 true,才会返回 true
- 只要有一边不是 true,那么就会返回 false
- `true && true` true
- `true && false` false
- `false && true` false
- `false && false` false
特殊情况:如果左边是flase,右边不参与运算
2. || 有一边为真则为真
- 进行 或 的运算
- 符号的左边为 true 或者右边为 true,都会返回 true
- 只有两边都是 false 的时候才会返回 false
- `true || true` true
- `true || false` true
- `false || true` true
- `false || false` false
0. !
- 进行 取反 运算
- 本身是 true 的,会变成 false
- 本身是 false 的,会变成 true
- `!true` false
- `!false` true
自增自减运算符
-
++-
进行自增运算
-
分成两种,前置++ 和 后置++
-
前置++,会先把值自动 +1,在返回
var a = 10; console.log(++a); // 会返回 11,并且把 a 的值变成 11 -
后置++,会先把值返回,在自动+1
var a = 10; console.log(a++); // 会返回 10,然后把 a 的值变成 11
-
-
--- 进行自减运算
- 分成两种,前置-- 和 后置--
- 和
++运算符道理一样
逻辑分支语句
if条件分支结构
<script>
if(true){ // 括号里的条件为true的时候执行{}里的代码
console.log('我执行了')
}
if(true){
console.log('我执行了')
}else{
console.log('条件为flase时执行')
}
if(true){
console.log('我执行了')
}else if(flase){
console.log('我执行了')
}
if(false){
console.log('我执行了')
}else if(false){
console.log('我执行了')
}else{
console.log('我执行了')
}
</scrpt>
switch条件分支结构
语法
switch (要判断的变量) {
case 情况1:
情况1要执行的代码
break
case 情况2:
情况2要执行的代码
break
case 情况3:
情况3要执行的代码
break
default:
上述情况都不满足的时候执行的代码
}
例:
var week = 2
switch (week) {
case 1:
alert('星期一')
break
case 2:
alert('星期二')
break
case 3:
alert('星期三')
break
case 4:
alert('星期四')
break
case 5:
alert('星期五')
break
case 6:
alert('星期六')
break
case 7:
alert('星期日')
break
default:
alert('请输入一个 1 ~ 7 之间的数字')
}
三元运算符
三元运算,就是用 **两个符号** 组成一个语句
三元运算只是对 **if else** 语句的一个简写形式
语法: 条件 ? 条件为 true 的时候执行 : 条件为 false 的时候执行
例:
var age = 18
age >= 18 ? alert('已经成年') : alert('没有成年')
循环结构
循环结构,就是根据某些给出的条件,重复的执行同一段代码
循环必须要有以下四部分内容组成
1.初始化
2.条件判断
3.要执行的代码
4.自身改变
while循环
- while,中文叫 当…时,其实就是当条件满足时就执行代码,一旦不满足了就不执行了
- 语法 while (条件) { 满足条件就执行 }
- 因为满足条件就执行,所以我们写的时候一定要注意,就是设定一个边界值,不然就一直循环下去了
// 1. 初始化条件
var num = 0;
// 2. 条件判断
while (num < 10) {
// 3. 要执行的代码
console.log('当前的 num 的值是 ' + num)
// 4. 自身改变
num = num + 1
}
do while循环
- 是一个和 `while` 循环类似的循环
- while 会先进行条件判断,满足就执行,不满足直接就不执行了
- 但是 do while 循环是,先不管条件,先执行一回,然后在开始进行条件判断
- 语法: do { 要执行的代码 } while (条件)
// 下面这个代码,条件一开始就不满足,但是依旧会执行一次 do 后面 {} 内部的代码
var num = 10
do {
console.log('我执行了一次')
num = num + 1
} while (num < 10)
for循环
- 和 while 和 do while 循环都不太一样的一种循环结构
- 道理是和其他两种一样的,都是循环执行代码的
- 语法: for (var i = 0; i < 10; i++) { 要执行的代码 }
// 把初始化,条件判断,自身改变,写在了一起
for (var i = 1; i <= 10; i++) {
// 这里写的是要执行的代码
console.log(i)
}
// 控制台会依次输出 1 ~ 10
break 终止循环
- 在循环没有进行完毕的时候,因为我设置的条件满足,提前终止循环
- 比如:我要吃五个包子,吃到三个的时候,不能在吃了,我就停止吃包子这个事情
- 要终止循环,就可以直接使用 `break` 关键字
- 有一个计数器的思想
for (var i = 1; i <= 5; i++) {
// 没循环一次,吃一个包子
console.log('我吃了一个包子')
// 当 i 的值为 3 的时候,条件为 true,执行 {} 里面的代码终止循环
// 循环就不会继续向下执行了,也就没有 4 和 5 了
if (i === 3) {
break
}
}
couninue
- 在循环中,把循环的本次跳过去,继续执行后续的循环
- 比如:吃五个包子,到第三个的时候,第三个掉地下了,不吃了,跳过第三个,继续吃第四个和第五个
- 跳过本次循环,就可以使用 `continue` 关键字
for (var i = 1; i <= 5; i++) {
// 当 i 的值为 3 的时候,执行 {} 里面的代码
// {} 里面有 continue,那么本次循环后面的代码就都不执行了
// 自动算作 i 为 3 的这一次结束了,去继续执行 i = 4 的那次循环了
if (i === 3) {
console.log('这个是第三个包子,掉地下了,我不吃了')
continue
}
console.log('我吃了一个包子')
}
双重for循环
for循环可以重复执行一个操作,当然也可以重复执行另一个循环,即for循环里面嵌套for循环,即双重for循环
循环的嵌套: 外层循环循环一次,内层就要循环完
实现九九乘法表:
<script>
/*
1x1=1
2x1=2 2x2=4
3x1=3 3x2=6 3x3=9
4x1=4 4x2=8 4x3=12 4x4=16
5x1=5 5x2=10 5x3=15 5x4=20 5x5=25
6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36
7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49
8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64
9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81
*/
for (var i = 1; i <= 9; i++) { //第一层for循环控制行
for (var j = 1; j <= i; j++) { //第二层for循环控制列数
var str += i + "x" + j + "=" + (i * j) + " "
document.write(i+'x'+j + '=' + i*j +' ')
}
document.write('<br/>')
console.log(str);
}
</script>
总结:
打印图形
使用双重for循环
1.外层循环打印行数
2.内层打印每行的元素
难点:找外层循环变量和每行打印元素的关系
函数
语法:
function 函数名(){
代码体
}
调用函数:
函数名()
注意:函数名命名规则同变量名命名规则
函数的参数
形参:
- 就是在函数内部可以使用的变量,在函数外部不能使用
- 行参的值是在函数调用的时候由实参决定的
function 函数名 (形参1,形参2...){
函数体
}
实参
- 在函数调用的时候给形参赋值的
也就是说,在调用的时候是给一个实际的内容的
多个参数的时候,是按照顺序一一对应的
函数名(实参1,实参2...)
参数的个数
形参比实参少
function fn(num1,num2){ // num1 = 10 num2 = 20
}
fn(10,20,30)
形参比实参多
function fun(num1,num2,num3){ // num1 = 10 num2 = 20 num3 = undefined
}
fun(10,20)
函数的返回值
return 返回的意思,其实就是给函数一个 返回值 和 终断函数
- 终断函数
- 当我开始执行函数以后,函数内部的代码就会从上到下的依次执行
- 必须要等到函数内的代码执行完毕
- 而 return 关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行
function fn (){
console.log(1)
console.log(2)
console.log(3)
// return以后 后面的代码就不执行了
return
console.log(4)
}
// 调用函数
fn()
- 返回值
return 关键字就是可以给函数执行完毕一个结果
function fn(){
return 100
}
console.log(fu()) // 100
函数的优点
1. 封装代码,使代码更加简洁
2. 复用,在重复功能的时候直接调用就好
3. 代码执行时机,随时可以在我们想要执行的时候执行
预解析
同名变量和函数的解析方式
- 如果遇到同名变量和函数,函数优先;如果执行变量赋值,同名的函数就转为变量,这时在调用函数,就会报错
- if条件不管成不成立语句块都会解析
- return语句后代码不执行,但会进行预解析
函数命名方式
声明式函数 function 函数名(){}
赋值式函数 var 函数名 = function () {}
区别:声明式函数可以预解析,赋值式函数不会预解析
变量作用域(重点)
- 什么是作用域,就是一个变量可以生效的范围
- 变量不是在所有地方都可以使用的,而这个变量的使用范围就是作用域
全局作用域
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
- 这个作用域会一直存在,直到页面关闭就销毁了
局部作用域
- 局部作用域就是在全局作用域下面又开辟出来的一个相对小一些的作用域
- 在局部作用域中定义的变量只能在这个局部作用域内部使用
- 在 JS 中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
- 有了作用域以后,变量就有了使用范围,也就有了使用规则
- 变量使用规则分为两种,访问规则 和 赋值规则的方式
- 嵌套的函数作用域,内层可以访问外层的,外层不能访问内层的
变量使用规则(重点)
访问规则
赋值规则
对象
定义:存储一些基本数据类型的一个集合
对象的创建方式
数组
创建一个数组
语法:字面量创建 var arr = []
构造函数创建 var arr = new Array()
数组的索引
- 索引,也叫做下标,是指一个数据在数组里面排在第几个的位置
- 注意: 在所有的语言里面,索引都是从 0 开始的
- 访问: 数组名[索引号] // 索引号对应的值
数组的length属性
- length 就是表示数组的长度,数组里面有多少个成员,length 就是多少=
数组的遍历
- 因为数组的索引就可以获取数组中的内容
- 数组的索引又是按照 0 ~ n 顺序排列
- 我们就可以使用 for 循环来循环数组,因为 for 循环我们也可以设置成 0 ~ n 顺序增加
- 我们把这个行为叫做 遍历
<script>
var arr = [1,2,3,4,5]
for(var = 0; i < arr.length; i++){
console.log(arr[i])
}
// 控制台循环打印 1,2,3,4,5
</script>
数据类型之间存储的区别
- 我们的存储空间分成两种 栈 和 堆
- 栈: 主要存储基本数据类型的内容
- 堆: 主要存储复杂数据类型的内容
- 数据类型之间的比较
- 基本数据类型是 值 之间的比较
- 复杂数据类型是 地址 之间的比较
数组的常用方法
- push 是用来在数组的末尾追加一个元素
var arr = [1,2,3]
arr.push(4)
console.log(arr)// [1,2,3,4]
- pop 是用来删除数组末尾的一个元素
var arr = [1,2,3]
arr.pop()
console.log(arr)// [1,2]
- unshift 是在数组的最前面添加一个元素
var arr = [1,2,3]
arr.unshift(4)
consloe.log(arr) // [4,1,2,3]
- shift 是删除数组最前面的一个元素
var arr = [1,2,3]
arr.shift()
console.log(arr) // [2,3]
- splice 是截取数组中的某些内容,按照数组的索引来截取
- 语法: splice(从哪一个索引位置开始,截取多少个,替换的新元素) (第三个参数可以不写)
var arr = [1,2,3,4,5]
splice(1,2) // 从索引1对应的值开始,截取两个
console.log(arr) // [1,4,5]
- reverse 是用来反转数组使用的
var arr = [1,2,3]
arr.reverse()
console.log(arr) // [3,2,1]
- sort 是用来给数组排序的
数组名.sort(function(a,b){return a-b}) - 升序排列
数组名.sort(function(a,b){return b-a}) - 降序排列
- concat 是把多个数组进行拼接
var arr = [1,2,3]
var newArr = arr.concat([4,5,6])
console.log(newArr) // [1,2,3,4,5,6]
- join 是把数组里面的每一项内容链接起来,变成一个字符串
var arr = [1,2,3]
arr.join('-')
console.log(arr) // 1-2-3
- indexOf 用来找数组中某一项的索引
var arr = [1,2,3]
var index = arr.indexOf(2)
console.log(index) // 1
如果要找的内容在数组中没有,就返回-1
可以用来判断数组中是否存在该元素
ES5常用数组遍历方法
- forEach 和 for 循环一个作用,就是用来遍历数组的
var arr = [1,2,3]
arr.forEach(function(item){
console.log(item) // 1,2,3
})
- map 和 forEach 类似,只不过可以对数组中的每一项进行操作,返回一个新的数组
var arr = [1,2,3]
var newArr = arr.map(function(item){
return item + 10
})
console.log(newArr) // [11,12,13]
- filter 把原始数组中满足条件的筛选出来,组成一个新的数组返回
var arr = [1,2,3]
var newArr = arr.filter(function(item){
return item > 1
})
console.log(newArr) // [2,3]
- find 遍历数组返回第一个满足条件的项
var arr = [1,2,3]
var newItem = arr.find(function(item){
return item > 1
})
console.log(newItem) // 2
- every 数组中是否每个元素都满足指定的条件, 全部满足返回true
- some 数组中是否有元素满足指定的条件,只要有一个满足返回true
- reduce() 方法接收一个方法作为累加器,数组中的每个值(从左至右) 开始合并,最终为一个值。
var arr = [1,2,3,4,5]
var sum = arr.reduce(function(s,item){
return s + item
},0)
console.log(sum) // 15
字符串
创建字符串
字面量创建
var str = 'hello'
构造函数创建
var str = new String('hello')
特点:字符串每个字符都对应索引号,索引号从0开始,与数组类似
字符串常用方法
- charAt(索引) 找到字符串中指定索引位置的内容返回
var str = 'hello'
var s = str.charAt(1)
console.log(s) // e
- indexOf 按照字符找对应的索引
var str = 'hello'
var index = str.indexOf('e')
console.log(index) // 1
- substring 是用来截取字符串使用的
- 语法:substring(开始索引,结束索引) 包含开始索引,不包含结束索引
var str = 'hello'
var newStr = str.substring(1,3)
console.log(newStr)// 'el'
- replace 用于在字符串中用一些字符替换另一些字符
var str="Visit Microsoft!"
document.write(str.replace('Microsoft', "school"))
输出 => Visit school!
- split 分割字符串,将分割之后的字符存入数组返回
var str = 'javascript-html-css'
var arr = str.splite('-')
console.log(arr) // [javascript,html,css]
- concat 连接两个字符串,返回连接之后的字符串
var str = 'hello'
var s1 = str.concat('world')
console.log(s1) // helloworld
- toLowerCase 和 toUpperCase 这连个方法分别是用来给字符串转成小写字母和大写字母
var str = 'hello'
var upper = str.toUpperCase()
console.log(upper) // HELLO
var lower = upper.toLowerCase()
console.log(lower) // hello
模板字符串
用反引号(``)引起来的就叫模板字符串
作用:简化字符串拼接,简化字符串换行输出
Math
处理数学问题, 特点:不需要创建对象,直接类型名.方法
Math.方法()
随机数random
- Math.random() 这个方法是用来生成一个 0 ~ 1 之间的随机数
- 每次执行生成的数字都不一样,但是一定是 0 ~ 1 之间的
- 生成的数字包含 0 ,但是不包含 1
取整方法round,ceil,floor
Math.ceil() 是将一个小数向上取整
vat num1 = 10.1
console.log(Math.ceil(num1)) // 11
var num2 = 10.9
console.log(Math.ceil(num2)) // 11
Math.floor() 是将一个小数向下取整
var num1 = 10.1
console.log(Math.floor(num1)) // 10
var num2 = 10.9
console.log(Math.floor(num2)) // 10
Math.round() 是将一个小数四舍五入变成一个整数
var num1 = 10.1
console.log(Math.round(num1)) // 10
var num2 = 10.6
console.log(Math.round(num2)) // 11
最大值 Math.max(值1,值2....)
最小值 Math.min(值1,值2...)
生成随机n~m的随机数
function getRandom(n,m) {
var r = Math.floor(Math.random() * (n - m) + m)
return r
}
let r = getRandom(10,30)
console.log(r)
Date
日期时间对象
1. 作用: 处理日期时间
2. 数据类型: 复杂数据类型 Date
3. 创建方式: 构造函数方法创建 var time = new Date() => 当前时间
创建指定日期时间
var time = new Date('2021-2-11 10:20:30')
var time = new Date(2021)
var time = new Date(2021,2)
var time = new Date(2021,2,11)
var time = new Date(2021,2,11,10,20,30)
Date常用方法
var time = new Date() // 获取当前时间
time.getFullYear() // 获取年
time.getMonth() // 获取月 月份要加1,因为计算机的月是从0开始的
time.getDate() // 获取日
time.getHours() // 获取小时
time.getMinutes() // 获取分
time.getSeconds() // 获取秒
time.getDay() // 获取格林威治时间(1970年1月1日(00:00:00 GMT))一周的星期几
time.getTime() // 获取当前时间到格林威治时间的毫秒数
格林威治时间 (1970年1月1日(00:00:00 GMT))
BOM
BOM介绍
javascript三大组成部份
- ECMAScript javascript基础语法 变量 数据类型 各种语句 函数 内置对象
- BOM 浏览器对象模型
- DOM 文档对象模型 BOM BOM,Browser Object Model,即浏览器对象模型。
其实就是操作浏览器的一些能力
我们可以操作哪些内容:
- 获取一些浏览器的相关信息(窗口的大小)
- 操作浏览器进行页面跳转
- 获取当前浏览器地址栏的信息
- 操作浏览器的滚动条
- 浏览器的信息(浏览器的版本)
- 让浏览器出现一个弹出框(alert/confirm/prompt)
BOM 的核心就是 window 对象
window 是浏览器内置的一个对象,里面包含着操作浏览器的方法 浏览器窗口启动时自动创建
学习BOM,本质学习window及其子对象
window对象常用方法
window对象常用方法
- 弹框 window.alert(提示信息)
- window.confirm(信息确认框) 提示信息 确定 取消 返回true false
- window.prompt(信息接收框) 文本输入框 确定 取消
注意:window对象是根对象,使用它的属性和方法时,window可以省略
定时器
定时器
window.setTimeout() 倒时计定时器(一次性)
window.setInterval() 循环定时器
var timeObj = window.setTimeout(function(){
//定时器到指定毫秒执行这里的代码
},时间)
//第一个参数: 执行函数
//第二个参数: 时间
//返回定时器对象
关闭倒计时定时器 clearTimeout(timeObj)
var timeObj = setInterval(function(){
//循环定时器执行代码
},循环间隔时间)
clearInterval(timeObj)
window宽高属性
var height = window.innerHeight //获取浏览器窗口高
var width = window.innerWidth //获取浏览器窗口宽
window滚动事件
//滚动事件属性
window.onscroll = function(){
//当滚动事件触发时,执行这里代码
} 获取滚动距离
1. 真正滚动是页面,而不是浏览器
2. 页面滚动的距离等行滚动条距离顶部高度
浏览器滚动的距离
DOM
获取HTML元素
document.getElementById('id属性值')
document.getElementsByClassName('class属性')
document.getElementsByTagName('标签名')
document.getElementsByName('name属性')
querySelector 和 querySelectorAll 是按照CSS的选择器来获取元素
document.querySelector('div') //获取页面中的第一个div
document.querySelectorAll('div') // 获取页面中所有的div,返回一个伪数组
操作元素内容
innerHTML
innerText
value // 获取表单的内容
操作CSS样式
style 行内样式
className class样式
classList.add()
classList.remove()
操作属性
根据属性名获取对应的属性值:getAttribute('属性名')
给标签设置属性值和属性名:setAttribute('属性名',"属性值")
根据属性名删除对应的属性名和属性值:removeAttribute('属性名')
事件
事件的组成部分
1.事件源 2.事件类型 3.事件处理函数
事件对象
每触发一个事件都会产生事件对象
divEle.onclick = function(e){
e = e || window.event // 获取事件对象(兼容性写法)
}
点击事件的光标坐标点获取
-
相对事件源(你点击的元素)offsetX,offsetY
-
相对于浏览器窗口(clientX,clientY)
-
相对于页面(pageX,pageY)
常见的事件
1.浏览器事件
2.鼠标事件
3.键盘事件
4.表单事件
5.触摸事件
事件的绑定方式
事件绑定
divEle.onclick = function(){
// 点击后执行的代码
}
事件监听
divEle.addEventListener('click',function(){
// 点击后执行的代码
})
事件目标对象
target
事件委托
阻止默认行为
e.preventDefault() : 非 IE 使用
e.returnValue = false :IE 使用
This关键字与ES6新特性
自调用函数
(function(){
console.log('我是自调用函数')
})
arguments
- 在函数内部自带的变量,表示所有实参的集合,是伪数组
- length属性 实参个数
this关键字
- 每一个函数内部都有一个关键字是 this
- 函数内部的 this 指向谁,取决于函数的调用方式
- 全局定义的函数的this指向window
- 普通对象内部的this指向当前对象
- 定时器的处理函数指向window
- 事件处理函数指向事件源
- 自调用函数指向window
- 重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系
改变this指向
- 函数名.call(要改变的this指向,参数1,参数2....)
- 函数名.apply(要改变的this指向,[参数1,参数2....])
- let newFn = fn.bind(要改变的this指向)
ES6新特性
- 在 ES6 的时候,多了两个关键字 let 和 const,也是用来声明变量的
let & const
变量定义
var num
let num = 100
const num = 100
var & let 的区别
1.let声明的变量不能变量提升(不能预解析),必须先声明再使用
2.let不允许重复声明变量
3.let声明的变量具有块作用域
全局作用域 局部作用域 块作用域
if(true){
let num = 100
}
console.log(num) // 报错
const 声明的变量也可以叫做常量
常量:值不变的量称为常量
const num = 100 // 常量
num = 200 // 报错
- 箭头函数
- 简化函数写法
赋值式函数:let fun = function (){}
箭头函数写法:let fun = () => {}
简写形式:
1.当形参只有一个时,括号可以不写
let fu = (参1,参2....)=>{}
fu(1,2)
let fu = 参1 => {}
fu(3)
2.当函数体只有一条语句时,花括号可以不写
var fu = ()=>{
console.log('')
}
var fu = ()=>
console.log('')
3.当函数体只有一条return语句时,花括号和return都可以不写
var fu = num => num
fu(10)
特点:
箭头函数中的this指向应用上下文本
箭头函数中如果出现this,它指向的上一作用域
- 结构赋值
简化访问简单对象和数组成员方式
var obj = {
name:'jack',
age:20,
gender:'男'
}
// let name = obj.name
// let age = obj.age
// let gender = obj.gender
// 解构对象
let {name , age , gender} = obj
var arr = ['jack','rose2','heqiang']
// 解构数组
let [a,b,c] = arr
- 展开运算符
作用:数组合并,对象合并
let arr = [1,2,3]
let arr1 = [4,5,6]
let arr2 = [...arr,...arr1]
// console.log(arr2) [1,2,3,4,5,6]
let obj = {
name:'jack',
age:20
}
let obj1 = {
...obj,
sex:'男'
}
console.log(obj1) // {name:'jack',age:20,sex:'男'}
- 字面量简化
当简单对象的属性名和属性值同名时,可以只写一个
let name = 'jack'
let age = 30
// let person = {
// name:name,
// age:age
// }
// | 简化
let person = {
name,
age
}
console.log(person)
正则表达式
什么是正则表达式:
某种模式去匹配一类字符串的公式
作用:用在字符串操作的时候,可以简化原生的js代码
实例:邮箱格式验证,以及密码强度验证等
定义方式:
构造函数:let reg = new RegExp('正则表达式')
字面量:let reg = /正则表达式/
正则相关的常用方法:
1. text() 正则对象的方法
写法:正则.test(字符串)
正则表达式跟字符串进行匹配,匹配成功返回true,匹配失败返回flase
2. search
正则去匹配字符串,如果匹配成功,就返回匹配成功的索引号,如果匹配失败就返回-1
写法:字符串.search(正则)
3. match
正则去匹配字符串,如果匹配成功,就返回匹配成功的数组,如果匹配不成功,就返回null
写法:字符串.match(正则)
4. replace
正则去匹配字符串,匹配成功的字符被新的字符串替换
写法:字符串.replace(正则,新字符串)
正则字符
普通字符:a-z 0-9
元字符:
\d \D
\w \W
\s \S
.
[ab]
[^ab]
限字符: 量词
+ 至少出现一次
例:/\d+/
JSON
JSON:轻量级的数据交换格式
语法:{"名称1":"值1","名称2":"值2"}
值的类型:数值类型,字符串,布尔,空,数组,简单对象
json存在形式:
字符串形式 let jsonStr = '{"username":"jack","age":20}'
对象形式 let jsonObj = {username:'jack'}
客户端与服务端进行json格式数据交换时
客户端:json对象转换为json格式字符串
服务端:收到json格式字符串转换为json对象
使用json对象的方法
JSON.parse(json字符串) 字符串转对象
JSON.stringify(json对象) 对象转字符串
localstorage
持久化存储
数据永久保存在那里,不会消失
localstorage是前端编程中用于持久化存储数据的一种技术实现
localstorage 是持久化存储对象
// 存储数据
localstorage.setItem(key,value)
key:字符串类型
value:基本数据类型 如果是对象需要转字符串
//获取数据
let value = localStorage.getItem(key)
//删除数据
localStorage.removeItem(key)
//清除所有数据
localStorage.clear()
面向对象编程
面向过程编程
=> 按步骤解决问题编程的方式
=> 如: 实现购物车数量加一功能
1. 加按钮 绑定事件
2. 找到点击的商品
3. 数量加一
4. 持久化存储数据
面向对象编程思想
解决问题的一种方式
现实生活中面向对象解决问题方式
=> 找解决问题的对象,调用其功能,解决问题
=> 如果对象不存在,就自己创建对象,封装功能,解决问题
注意: 自己创建对象,封装功能
程序问题
字符串 "javascript-html-css"
按'-'分割字符串,[javascript,htnml,css]
面向对象
let str = "javascript-html-css"
let arr = str.split('-')
创建对象
function Preson (){
this.name = 'jack'
this.age = 30
this.say = function(){
console.log('shuo hua')
}
}
let p1 = new Preson()
p1.say()
console.log(p1.name)
面向对象常见概念
构造函数、实例、引用变量、对象名,对象概念
对象:
内置对象
实例对象 - 实例 new 语句出来的就是实例对象
原型对象 ->原型
每个构造函数都有一个原型对象
通过构造函数的prototype属性访问. Person.prototype
原型对象存在的意义?
原型对象 构造函数 实例对象 三者关系
原型链
原型链:多个原型通过隐藏__proto__连接起来,形成的一种链式结构,称为原型链.
原型链作用:访问对象属性或方法时,会沿着原型链上的所有原型进行查找,至到根null为止
网络编程
Nodejs
Nodejs是一个应用编程平台,能运行javascript语言编写的代码,提供了javascript运行环境, 基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。 提供了大量应用编程接口API,在处理http网络、数据库、文件等操作时非常方便.
NodeJS开发环境安装 官网下载地址nodejs.cn/download/
检测环境是否安装成功 在命令行输入 node -v 结果是版本号就说明安好了
创建一个web服务器
/**
web服务器
使用javascript代码创建web服务
=> web服务
提供通过浏览器访问网络资源这种服务,web服务
以前通过web服务软件如nginx实现
=> 通过nodejs提供的http模块实现web服务
1.安装nodejs环境
2. 引入http模块
let http = require('http)
http.createServer()
*/
const http = require('http') //引入http模块
//创建web服务
const server = http.createServer(function (request, response) {
//request 请求
//response 响应
//解决中文乱码
response.writeHead(200, {
'content-type': 'text/html;charset=utf-8'
})
response.write('hello world nodejs 这是我响应的内容') //写入内容到响应对象response
response.end() //结束写入,响应内容
})
//启动web服务
server.listen(3000, () => console.log('web服务启动成功,监听 3000端...'));
区别请求内容
// 创建http模块
const http = require('http')
// 创建服务器对象
const server = http.createServer(function (request, response) {
// request 请求
// response 响应
//解决中文乱码
response.writeHead(200, {
'content-type': 'text/html;charset=utf-8'
})
// 区别请求内容
if(request.url == '/login'){
let strLogin = `<div>
<form>
<input type="text" name="username"/> <br>
<input type="password" name="password"/> <br>
<input type="submit"/>
</form>
</div>
`
response.write(strLogin)
}else{
response.write('此模块还在开发中')
}
response.end() //结束写入,响应内容
})
// 启动web服务
server.listen(3000, function () {
console.log('web服务启动成功,监听 3000端...')
})
数据库常用的SQL语句
数据库常用的SQL语句
增:INSERT INTO 表名(列1, 列2,...) VALUES (值1, 值2,....)
例:INSERT INTO product(id, name,...) VALUES (1004, vue高级编程,....)
改:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
例:UPDATE product SET price = 38.34 WHERE id = 1004
查:SELECT * FORM 查找所有
SELECT id,name,... FROM product
删:DELETE FROM 表名称 WHERE 列名称 = 值
例:DELETE FROM product WHERE id = 1001
注意:不区分大小写
前后端分离
ajax 异步网络通讯技术
ajax的书写步骤
获取XMLHttpRequest对象
const xhr = new XMLHttpRequest() '括号可以不写'
常用方法:
open(method,URL) 建立服务器连接
send(content) 发送请求 注意:method是get的时候不用写参数
onreadystatechange 指定回调函数
就绪状态码-xhr.readyState 返回值0-4
状态码status
xhr.responseText 服务端响应的内容
function getProductList() {
//获取xhr对象
let xhr = new XMLHttpRequest()
// 建立连接
xhr.open('get', 'http://10.7.162.100:3000/login')
// 发送请求
xhr.send()
// 处理响应
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
let res = xhr.responseText
document.querySelector('p').innerHTML = res
} else {
alert(xhr.status+xhr.statusText)
}
}
}
}
同源策略&跨域
同源策略:同源策略是浏览器的一个安全功能,不同源的网页脚本在没有明确授权的情况下,不能读写对方资源。所谓同源是指"协议+域名+端口"三者相同。
跨域:使用AJAX技术(XMLHttpRequest 对象),从一个网页去请求另一个网页资源时,违反浏览器同源策略限制,引起的安全问题,称为跨域
跨域解决方案
- jsonp技术
+ 利用网页中script img link 标签元素,在访问不同源资源时不会违反同源策略安全限制
+ 发送请求:
构造script标签,将请求接口url地址作为src属性的值,发起请求
+ 响应数据:
后端支持: 将响应的数据,封装在函数体中
比如: {username:'admin',password:123}
callback({username:'admin',password:123})
前端 函数名
function callback(result){
result -> {username:'admin',password:123}
}
+ jsonp技术只支持get 请求
ajax&promise
异步和同步
同步操作指: 一个任务执行完成后再执行下一个任务
异步操作指:多个任务同时并发执行
当一个操作开始执行后,主程序无需等待它的完成,可以继续向下执行。
此时该操作可以跟主程序同时(并发)执行。
网络ajax请求
定时器
异步任务的结果是怎么处理的呢?
1. 回调函数处理异步结果
回调函数
将函数callBack作为参数传给函数fun, 在函数fun中以形参方式进行调用, 函数callBack就称为回调函数
简单理解为: promise是对异步操作的封装,封装异步文件读写, ajax异步网络请求...
promise封装
// let promise = new Promise(function(resolve,reject){
// // 封装一个定时器任务
// setTimeout(function(){
// if(true){
// resolve('成功处理')
// }else{
// reject('失败处理')
// }
// },1000)
// })
// promise.then(function(result){
// console.log('then',result)
// })
// promise.catch(function(err){
// console.log('catch',err)
// })
function myPromise (){
let promise = new Promise(function(resolve,reject){
setTimeout(function(){
if(true){
resolve('处理成功')
}else{
reject('处理失败')
}
},1000)
})
return promise
}
// myPromise().then(function(result){
// console.log('then',result)
// }).catch(function(err){
// console.log('catch',err)
// })
myPromise().then(result=>console.log(result)).catch(err=>console.log(err))
链式调用
Promise链式调用:
myAjaxPromise({
method:'get',
url:'第一个请求'
}).then(result1=>{
return myAjaxPromise({
method:'get',
url:'第二个请求'
})
}).then(result2=>{
return myAjaxPromise({
method:'get',
url:'第三个请求'
})
}).then(result3=>{
//result3
})
promise常用的方法
Promise.all([promise1,promise2]).then(results=>{
})
Promise.race([promise1,promise2]).then(result=>{
})
let promise = Promise.resolve('成功内容')
promise.then(result=>{
})
cookie
sync/await
异步操作
console.log(主程序1)
myAjax({
method:'get',
url:'请求地址',
success:function(result){
//处理异步操作成功的结果
}
})
let result = myAjax({method:'get',url:'请求地址'})
console.log(主程序2)
console.log(主程序3)
async/await
=>作用: 异步操作用同步的写法实现
=> 使用方式:
- async关键字写在函数头部, 表示该函数是一个异步执行的函数
- await关键字表示等待的意思, 只能用在async异步函数中, 后面跟promise对象
=> 等待promise封装的异步操作执行完,返回结果
cookie
=> cookie前端本存储数据的一种技术
=> 文本字符串形式: 每条cookie数据以key=value形式存储
'username=admin;password=123'
=> 存储大小4k
=> 存储时间
可以自己定义
默认会话级别
=>域名有关
=>使用cookie
let cookie = document.cookie
document.cookie = 'username=admin'
document.cookie = 'password=123'
=>浏览器查看cookie
继承&闭包&jQuery
继承
面向对象特性
封装性
多态性
一个事物有多种表现形式
let a = 100 //number
a = '100' //string
继承性
继承
现实生活
儿子可以继承父亲的财产
软件世界
重点: 子类继承父类,子类就拥有父类属性和方法
1. 子类
2. 父类
3. 继承内容:属性和方法
构造函数继承
- 在子类的构造函数中调用父类的构造函数,通过call方法改变this指向
Person.call(this)
- 构造函数继承-继承构造函数中属性和方法
拷贝继承
- 遍历父类原型对象,拷贝父类原型对象属性和方法到子类原型对象上
for(let key in Person.prototype){
Student.prototype[key] = Person.prototype[key]
}
function Preson() {
this.name = 'jack'
this.say = function () {
console.log('说话')
}
}
Preson.prototype.eat = function () {
console.log('吃饭')
}
// console.log(Preson.prototype)
function Student() {
Preson.call(this) // 实现子类继承父类的属性和方法
this.age = 20
this.readbook = function () {
console.log('读书')
}
}
for (let key in Preson.prototype) {
Student.prototype[key] = Preson.prototype[key]
}
let s1 = new Student()
s1.readbook()
s1.say()
s1.eat()
原型继承
原型继承:就是把父类的实例化对象赋值给子类的原型对象
function Preson() {
this.name = 'jack'
this.say = function () {
console.log('说话')
}
}
Preson.prototype.eat = function () {
console.log('吃饭')
}
function Student() {
this.age = 20
this.readbook = function () {
console.log('读书')
}
}
Student.prototype = new Preson() // 原型继承
let s1 = new Student()
s1.readbook()
s1.say()
s1.eat()
原型继承传参
//Person人类 - 父类
function Person(name) {
this.name = name
}
Person.prototype.eat = function () {
console.log(this.name, '吃饭')
}
//Student学生类 -子类
function Student(num, name) {
Person.call(this, name)
this.num = num
}
//原型继承 - 父类实例对象赋值给子类原型
Student.prototype = new Person()
// let s1 = new Student(1001)
let s1 = new Student(1001, 'rose')
s1.eat()
console.log(s1.name);
ES6的继承
ES6的继承,使用extends关键字
class 子类 extends 父类{}
class Preson {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
say() {
console.log('说话')
}
}
class Driver extends Preson {
constructor(name, age, sex) {
super(name, age, sex)
}
openCar() {
console.log('开车')
}
}
闭包
函数高级用法 - 这种写法称为 :闭包
闭包形成条件:
1. 有函数嵌套,内层函数被返回(显示,隐式)
2. 内层函数访问外层函数私有变量
3. 内层函数被引用
闭包作用:
1. 生成不被销毁的执行空间,生成块作用域。 缺点:占用内存空间.
2. 外层函数访问内层函数私有变量
3. 设计模式在使用闭包
jQuery
语法:$(选择器).atcion()
jQuery 选择器
- 普通选择器
类选择器
id选择器
标签选择器
- 高级选择器
- 层次选择器
m n 选择m的后代
m>n 选择m的子代
- 属性选择器
input[name="username"]
- 伪类选择器
div li:nth-child(n)
....
- jQuery 的查找方法
- 查找元素集合的第一个元素 first() 和最后一个元素last()
$('div').first()
- 查找祖先 parent() parents() parentUntil()
$('div').parent() // 获取第一个父节点
$('div').parents() // 获取所有的父节点,包括body,html
$('div').parentUtil('body') // 获取到body的父节点,不包含body
- 查找后代 children() find()
$('div').child() // 获取所有的子几点,以伪数组返回
$('div').find('.l1') // 获取.l1这个子节点
- 向前查找兄弟节点 prev() prevAll() prevUntil()
$('div').prev() //向前查找一个
$('div').prevAll() //向前查找所有
$('.box3').prevUntil('.box1') //向前查找到.box1的兄弟节点
- 向后查找兄弟节点 next() nextAll() nextUntil()
- 查找除了自己以外的兄弟节点 siblings()
- 操作内容
- $(选择器).html() => innerHTML
- $(选择器).text() => innerText
- $(选择器).val() => value
- 操作样式
- $(选择器).css('width','100px') 行内样式
- $(选择器).addClass(样式类名) 添加
- $(选择器).removeClass(样式类名) 删除
- 操作属性
- $(选择器).prop('id','box') => 只能添加原本就有的属性
- $(选择器).attr('id-index','1') => 可以添加自定义的属性
- $(选择器).removeAttr('id-index') 删除某一个属性
- 操作事件
- 绑定点击事件 $(选择器).on('click',function(){})
- 绑定点击事件,并传参 $(选择器).on('click',{name:'jack'},function(e){
console.log(e)
console.log(e.data) // {name:'jack'}
})
- 事件委托
$('div').on('click','button',function(){})
- 移出事件
- 可以直接绑定,不用on的事件
- click hover blur
- 查找元素集合eq(索引) 可以访问该索引对应的节点
('li').eq(1)
- 查找元素在元素集合中的索引位置 (选择器).index() // 返回对应节点的索引
jQuery动态操作dom节点
创建节点
$("<p>").text("内容"); => <p>内容</p>
添加节点
parent.append(child) 向父元素加入子元素,作为父节点最后的一个孩子
parent.prepend(child) 向父元素加入子元素,作为父节点第一个孩子
brother.after(obj) 在某个兄弟节点之后插入一个节点
brother.before(obj) 在某个兄弟节点之前插入一个节点
删除节点
$('ul').empty()执行后会将ul下面的所有子元素删除,保留ul
$('ul').remove()执行后会将ul下面所有的子元素删除
替换节点
$('<ol>').replaceAll('ul') 使用新节点ol替换旧节点ul
复制节点
$('li').clone(true/flase)
flase:自己身上的事件要不要复制
true:所有子节点身上的事件要不要复制
jQuery对象与Dom对象转换
jQuery对象->Dom对象
const jqObjToDom = $(".d1")[0]; //jquery对象转Dom对象 方法一
const jqObjToDom = $(".d1").get(0); //jquery对象转Dom对象 方法二
Dom对象->jQuery对象
const domObj = document.querySelector(".d2"); //dom对象
const domToJqObj = $(domObj);
元素尺寸位置
元素尺寸
- 操作元素的宽高 $('div').height() $('div').width() 不半酣padding和border
- 包含padding,不包含border
$('div').innerHeight()
$('div').innerWidth()
- 包含padding和border
$('div').outerHeight()
$('div').outerEidth()
- 包含padding和border和margin
$('div').outerHeight(true)
$('div').outerEidth(true)
jQuery动画效果&ajax
动画效果
- 淡入淡出
$('div').fadeIn() 淡出
$('div').fadeOut() 淡入
$('div').fadeToggle() 切换淡出淡入
- 滑入滑出
$('div').slideDown()
$('div').slideUp()
$('div').slideToggle()
- 隐藏显示
$('div').hide 隐藏
$('div').show 显示
$('div').toggle 切换显示与隐藏
ajax
- $.get({})
- $.post({})
- $.ajax({})
工具
npm包管理工具
在安装nodejs的时候,同时也把npm安装好了
- 检查安装是否成功 npm -v 回车
输出版本号代表安装成功
- 使用npm
npm install 包
npm install 包 -g -g表示全局安装
下载jquery
在命令行输入 npm install jquery
- 镜像切换nrm
npm install nrm -g =>安装全局nrm
+ nrm test =>查看镜像源地址的网速
+ nrm use taobao => 切换镜像源
cnpm 默认taobao镜像
- npm install cnpm -g
- cnpm install jquery
- 卸载包
npm uninstall jquery
npm包在项目中如何使用
1.创建一个项目
2. package.json文件 => npm init 项目初始化命令 / npm init -y 默认配置 (初始化以后就会得到一个package.json文件)
项目配置文件
项目名
项目作者
项目引用的包
项目版本
...
3. 下载的第三包,都会被记录到package.json文件
4. 项目开发完成之后部署到服务器
不需要复制node_moudles下所有第三包文件
在服务器执行 npm install
会根据package.json文件中记录的包信息自动下载
5. 下载包分类
开发环境
npm install jquery -D
生产环境
npm install jquery -S
package.json
"dependencies": {
"mysql": "^2.18.1"
},
"devDependencies": {
"jquery": "^3.6.0"
}
package.json记录的第三方依赖
+ dependencies
=>表示的你项目的项目依赖
=>比如jquery, swiper
=>指项目运行需要用到的内容,将来上线以后也需要用到的内容
+ devDependencies
=>表示的你项目的开发依赖
=>比如gulp
=>指项目开发阶段需要用到的内容,将来上线以后不需要用到的
gulp第三方包最好是放在devDependencies
+在你安装第三方依赖的时候,书写$ npm install -D 包名
+就会把依赖项记录再devDependencies
CSS预处理工具sass
- 安装全局sass环境
npm install sass -g
- sass文件后缀有两种
.sass & .scss
区别就是.scss有{}, .sass没有{}
- 使用
1.创建一个index.scss为后缀的文件
2.右键在集成终端打开,输入命令 sass index.scss index.css (这种只能编译一次,不是很方便)
3.会自动生成一个index.css文件,然后引入到html中即可
4.之后的样式就在.scss里写
实时编译:在.scss文件中写样式,会实时的编译到.css文件中
命令 sass --watch index.scss:index.css
实时监控目录:单独创建一个sass的文件夹和css的文件夹
1.在sass文件夹的父文件夹右键打开终端,输入命令sass --watch scss:css
2.这样就能做到,你在sass文件夹里创建的scss文件会自动创建到css文件夹下
- sass 语法
- 变量 $c:red;
div{
color:$c;
}
编译为:
div{
color:red;
}
- 嵌套(比较常用的)
div{
color:red;
p{
font-size:20px;
}
}
编译为:
div{
color:red;
}
div p{
font-size:20px;
}
- 嵌套中的 &
div{
color:red;
&:hover{
color:blue;
}
}
编译为:
div{
color:red;
}
div:hover{
color:blue;
}
- 群组嵌套
p1,p2,p3{
color:red;
div{
font-size:40px;
}
}
编译为:
p1,p2,p3{
color:red;
}
p1 div,p2 div,p3 div{
font-size:40px;
}
- 混入(混合器)
就是在scss里封装一个函数,在需要用的就调用(也可以传参,和函数一样的)
定义方式:@mixin 名字(){}
调用方式:@include 名字();
- 继承
简单理解就是把重复的代码写在一起,当后面有需要相同的样式时,继承过来就好了
使用关键字:@extend
举例:
div{
width:100px;
height:100px;
font-size:30px;
}
p{
@extend div;
color:red;
}
- 导入文件
- 条件 @if
- 循环 @for
git版本控制工具
安装
官网https://git-scm.com/ 无脑下一步
检查是否安装成功
git --version
git 分区
- 工作区(本地目录)
- .git 版本库(里面分为暂存区和历史区)
本地库操作步骤小结
- 1.进入需要被git版本管理的目录
- 2.初始化版本库 git init
- 3.初始化用户名和邮箱,告诉git时谁提交的版本 git config --global user.name '名字'
git config --global user.email '邮箱地址'
(一台电脑只用初始化一次)
- 4. 添加工作区内容到版本库 暂存区 git add .
- 5. 添加暂存区内容到历史区 git commit -m "提示信息"
- 6. 查看提交到历史区的日志 git log
- 7. 不小心删除工作区内容,可以从版本库找回来 git reset --hard 版本号
本地分支
作用:大家互不干扰,每一个功能都有独立的功能分支
主分支:master
开辟一个分支
- git branch 分支名 git branch login
查看当前分支
- git branch *代表你当前所在的分支
切换分支
- git checkout login
合并分支
- 注意要先切换到master分支上
- git merge login 表示把login分支合并到master上
实现步骤
1.先创建分支 git branch login
2.切换分支 git checkout login
3.再创建模块进行开发
4.开发完以后,git add .添加到暂存区
5.git commit -m '提示信息' 添加到历史区
git远程库 (一个项目对应一个远程库)
- getee官网注册账号,注册好了以后,创建库
- 建立连接(第一次)
- 1.git remote add origin 库的地址
- 2.git push -u origin "master"
- 之后修改了代码,先添加到历史区,再git push 就可以添加到远程库了
- 其他开发者如果需要这份代码
- 直接 git clone 仓库地址
- 当有人更新了远程库的代码时,我们不用再git clone一次,直接拉取 git pull 就可以更新到最新版本的代码了
gulp自动构建打包工具
gulp在项目中的使用步骤
1.准备一个项目
+ 需求:你要确定好自己的目录结构
你要分开源码和打包以后的内容
+ 确定自己的目录结构
- xiaomi
- src 源码
+ pages 放html文件
+ CSS 放CSS文件
+ js 放js文件
+ sass 放sass文件
+ images 图片文件
+ videos 视频文件
+ audios 音频文件
+ lib 第三方文件(jquery, swiper, ...)
+ fonts 字体图标文件
...
2.准备一个gulpfile.js 的文件
+ 必须有
+ gulp进行打包的依据
+ 每一个项目都需要一个gulpfile.js
+ 我们再这个文件里面进行本项目的打包配置
+ gulp再运行的时候,会自动读取gulpfile.js 文件里面的配置
+ 按照你再gulpfile.js 文件里面的配置进行打包工作
+ 注意: **直接写在项目根目录,和src同级**
3.再项目里面再次安装gulp
+ 注意: **项目里面的gulp 是以第三方模块的形式出现的**
+ 专门给你提供配置打包流程的API的
+ 每一个项目都要安装一次
4.再gulpfile.js 里面书写配置文件
+ 书写你该项目的打包流程
+ 书写完毕以后,按照打包流程去执行gulp 指令运行gulpfile.js 文件
gulp的常用API
+ 前提:下载gulp 第三方,导入以后使用
1. gulp.task()
=> 语法: gulp.task(任务名称,任务处理函数)
=> 作用: 创建一个基于流的任务
=> 例子: gulp. task('htmlHandler', function () {
//找到html源文件,进行压缩,打包,放入指定目录
})
2. gulp.src()
=> 语法: gulp.src(路径信息)
=> 作用:找到源文件
=> 书写方式
2-1. gulp.src(' ./a/b.html')
-> 找到指定一个文件
2-2. gulp.src(' ./a/* .html' )
->找到指定目录下,指定后缀的文件
2-3. gulp.src('./a/**')
->找到指令目录下的所有文件
2-4. gulp.src(' ./a/** /*')
->找到a目录下所有子目录里面的所有文件
2-5. gulp.src(' ./a/** /* .htm1' )
->找到a目录下所有子目录里面的所有.html文件
3. gulp.dest()
=> 语法: gulp.dest(路径信息)
=> 作用:把一个内容放入指定目录内
=> 例子: gulp.dest(' ./abc ')
->把他接收到的内容放到abc 目录下
4. gulp.watch()
=> 语法: gulp.watch(路径信息, 任务名称)
=> 作用:监控指定目录下的文件,一旦发生变化,从新执行后面的任务
=> 例子: gulp .watch(' ./src/pages/* .html', htmIHandler )
->当指定目录下的html 文件发生变化,就会执行htmlHandler 这个任务
5. gulp.series()
=>语法: gulp.series(任务1, 任务2,任务3,
=>作用:逐个执行多个任务,前一个任务结束,第二个任务开始
6. gulp. parallel()
=>语法: gulp. paralle1(任务1, 任务2,任务3, ...)
=>作用:并行开始多个任务
7. pipe()
=>管道函数
=>所有的gulpAPI都是基于流
=>接收当前流,进入下一个流过程的管道函数
=>例子:
gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc' ))
gulp版本3的写法
gulp.task('css',function(){
return gulp
.src('./src/css/index.css')
.pipe(cssmin())
.pipe(gulp.dest('./dist/css/'))
})
guLp@4的标准书写,需要再gulpfile.js文件里面把这个函数名导出
function css (){
return gulp
.src(' ./src/css/* .css')
.pipe(cssmin())
.pipe(gulp .dest(' ./dist/css/'))
}
导出这个任务
module exports.css = css
gulp常用的插件
+ gulp的各种插件就是用来执行各种各样的压缩混淆转码任务的
1. gulp-cssmin (压缩css文件)
=>下载:npm i gulp-cssmin -D
=>导入: const cssmin = require('gulp-cssmin')
=>导入以后得到一个处理流文件的函数
=>直接再管道函数里面执行就好了
2. gulp-autoprefixer (添加前缀的)
=>下载: npm i gulp-autoprefixer -D
=>导入: const autoPrefixer = require('gulp-autoprefixer')
=>导入以后得到一个处理流文件的函数
=>直接再管道函数里面使用,需要传递参数
-> { browsers: [要兼容的浏览器] }
3. gulp-sass (把sass文件编译为css文件)
=>下载: npm i gulp-sass -D ; npm i sass
=>导入sass与 gulp-sass
-> const sass = require('gulp-sass')(require('sass'));
=>导入以后得到一个可以处理流文件的函数,直接再管道函数里面执行就可以了|
4. gulp-uglify
=> 把JS文件压缩
=> 下载: npm i -D gulp-uglify
=> 导入: const uglify = require(' gulp-uglify' )
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数中使用就可以了
=> 注意:你不能写ES6语法,一旦有了ES6语法就会报错
5. gulp-babel
=> 专门进行ES6转ES5的插件
=> 下载:
-> npm i -D gulp-babel@7.0.1
-> npm i -D babel-core
-> npm i -D babel-preset-es2015
=> 导入:
-> const babel = require('gulp-babel')
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数内部使用,需要传递参数
6. gulp-htmlmin (压缩html文件)
=> 下载: npm i -D gulp-htmlmin
=> 导入: const htmImin = require( ' gu1p-htm1min' )
=> 导入以后得到一个可以处理流文件的函数
=> 直接再管道函数里面调用,需要传递参数
=> 参数
-> { // 通过你配置的参数来进行压缩
collapseWhitespace: true, //表示移出空格
removeEmptyAttributes: true, //表示移出空的属性(仅限于原生属性)
collapseBooleanAttributes: true, //移出checked类似的布尔值属性
removeAttributeQuotes: true, //移出属性上的双引号
minifyCSS: true, // 压缩内嵌式css代码(只能基本压缩,不能自动添加前缀)
minifyJS: true, //压缩内嵌式JS代码(只能基本压缩,不能进行转码)
removeStyleLinkTypeAttributes: true, //移出style和link标签上的type
removeScriptTypeAttributes: true, //移出script标签上默认的type属性
}
7.按顺序批量执行任务
=> series 将任务按顺序执行
=> exports.default暴露一个默认任务
=> 根目录下可执行运行默认任务,通过 gulp 命令
-> exports.default = gulp.series('css', 'sass', 'js', 'html', 'lib', 'static')
-> 执行: gulp 即可
8.同时批量执行任务
=> parallel 多个任务同时执行
=> exports.default暴露一个默认任务
=> 根目录下可执行运行默认任务,通过 gulp 命令
-> exports.default = gulp.parallel('css', 'sass', 'js', 'html', 'lib', 'static')
-> 执行: gulp 即可
9.清除 DIST 文件夹
=> 下载:npm i -D gulp-clean
10.自动打开浏览器
=> npm i -D gulp-webserver
11.修改内容自动刷新
不需要下载
GULP完整配置文件
- npm i gulp-cssmin -D 压缩css文件
- npm i gulp-sass -D ; npm i sass 把sass文件编译为css文件
- npm i -D gulp-uglify 压缩js文件
- gulp-babel 专门进行ES6转ES5的插件
=> 下载:
-> npm i -D gulp-babel@7.0.1
-> npm i -D babel-core
-> npm i -D babel-preset-es2015
- npm i -D gulp-htmlmin 压缩html文件
- npm i -D gulp-clean 清除 DIST 文件夹
- npm i -D gulp-webserver 自动打开浏览器
gulpfile.js 文件内容
const gulp = require('gulp') // 引入gulp
const cssmin = require('gulp-cssmin') // 引入cssmin 压缩css文件的
const sass = require('gulp-sass')(require('sass')); //引入sass与 gulp-sass 把scss文件编译为css文件
// 3-1. 引入 gulp-uglify 压缩js文件
const uglify = require('gulp-uglify')
// 3-2. 引入 gulp-babel
// es6 转 es5 虽然需要下载三个依赖,但是只需要引入一个 gulp-babel 就可以了
const babel = require('gulp-babel')
// 4. 引入 gulp-htmlmin 压缩html文件
const htmlmin = require('gulp-htmlmin')
// 5. 引入 gulp-clean 清除 DIST 文件夹
const clean = require('gulp-clean');
// 7. 引入 gulp-webserver 自动打开浏览器
const webserver = require('gulp-webserver')
gulp.task('css', function () {
return gulp.src('./src/css/**')
.pipe(cssmin())
.pipe(gulp.dest('./dist/css'))
})
gulp.task('sass', function () {
return gulp.src('./src/sass/**')
.pipe(sass())
.pipe(cssmin())
.pipe(gulp.dest('./dist/css'))
})
// 3. 创建一个 js 任务
gulp.task('js', function () {
return gulp
.src('./src/js/**')
.pipe(babel({
presets: ['es2015']
}))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'))
})
// 4. 创建一个 html 任务
gulp.task('html', function () {
return gulp
.src('./src/pages/**')
.pipe(htmlmin({
removeEmptyAttibutes: true, // 移出所有空属性
collapseWhitespace: true // 压缩 html
}))
.pipe(gulp.dest('./dist/pages'))
})
gulp.task('lib', function () {
return gulp.src('./src/lib/**')
.pipe(gulp.dest('./dist/lib'))
})
gulp.task('static', function () {
return gulp.src('./src/static/**')
.pipe(gulp.dest('./dist/static'))
})
// 8. 创建一个 clean 任务
gulp.task('clean', function () {
return gulp
.src('./dist', {
allowEmpty: true
}) // {allowEmpty: true} dist目录不存在时配置
.pipe(clean())
})
// 9. 创建一个 webserver 任务
gulp.task('webserver', function () {
return gulp
.src('./dist')
.pipe(webserver({
host: 'localhost', // 配置打开浏览器的域名
port: 3000, // 配置打开浏览器的端口号
livereload: true, // 自动刷新浏览器
open: './pages/index.html' // 默认打开 dist 文件夹下的哪个文件
}))
})
// 10. 创建一个 watch 任务
gulp.task('watch', function () {
gulp.watch('./src/css/**', gulp.parallel('css'))
gulp.watch('./src/sass/**', gulp.parallel('sass'))
gulp.watch('./src/js/**', gulp.parallel('js'))
gulp.watch('./src/pages/**', gulp.parallel('html'))
gulp.watch('./src/lib/**', gulp.parallel('lib'))
gulp.watch('./src/static/**', gulp.parallel('static'))
})
exports.default = gulp.series('clean',
gulp.parallel('css', 'sass', 'js', 'html', 'lib', 'static'),
gulp.series('webserver','watch'))
模块化编程
模块化规范
CommonJS 语法
ES6规范
Map和Set
Map 和 Set 是 ES6 新增的两个数据类型
都是属于内置构造函数
使用 new 的方式来实例化使用
// 实例化的时候直接添加数据要以数组的形式添加
const s = new Set([1, 2, 3, {}, function () {}, true, 'hwllo'])
console.log(s)
Set存储一系列无序数据的集合
=>特点:存储的元素不重复
=>创建方式
let set = new Set()
=>常用的属性
-> size 是一个属性
=>常用的方法
-> add()
-> delete()
-> clear()
-> forEach() 遍历Set
应用:
=> 数组去重
let arr = [10,20,30,10,20]
let set = new Set(arr)
arr = [...set]
console.log(arr)// [10,20,30]
Map是一个数据集合,是一个很类似于 对象 的数据集合
const m = new Map([[{}, {}], [function () {}, function () {}],[true, 1]])
size : 用来获取该数据类型中数据的个数
delete : 用来删除该数据集合中的某一个数据
set : 用来向该数据集合中添加数据使用
get : 用来获取该数据集合中的某一个数据
clear : 清除数据集合中的所有数据
has : 用来判断数据集合中是否存在某一个数据
Symbol类型
ES5中包含5种原始类型:字符串、数字、布尔值、null和undefined。ES6引入了第6种基本数据类型——Symbol
ES6引入Symbol的原因:
ES5的对象属性名都是字符串,很容易造成属性名冲突。
比如,使用了一个他人提供的对象,想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。
如果有一种机制,保证每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突。