【JS】简单复习及ES6
视频链接:https://www.bilibili.com/video/BV1Y84y1L7Nn
一、JavaScript ECMAScript
JavaScript语言基础。
10. 变量的声明 var 与 let
首先说结论,放弃 var,使用 let。
let 为了解决 var 的一些问题:
var 声明:可以先使用在声明(不合理)
var 声明过的变量可以重复声明(不合理)
比如变量提升、全局变量、没有块级作用域等等。
var的变量提升和块级作用域容易搞出bug还不好检查,造成函数作用域甚至全局作用域内的变量污染,会有很多问题。
12. 常量 const
使用 const 声明的变量称为“常量”。
const 声明的变量,永远不会改变。
使用方法和变量一样,类似于 let ,但变量的值无法被修改。
const A = 123;
这个A的值永远不会改变。
1.常量不允许重新赋值,不能更改值
2.常量声明的时候必须赋值(初始化)
所以,不需要重新赋值的数据使用 const
14. 字符串类型
''单引号、""双引号、``反引号包裹的数据都叫字符串。推荐使用单引号 ''
空字符串:' '
注意:
1.引号必须成对使用
2.单引号双引号可以互相嵌套,比如:let name = '我的名字是"猫"'
,引号会找最近的匹配,就是外双內单,外单内双。
3.可以使用转义字符 \ ,输出单引号或双引号。
拼接字符串:
'我叫' + '小猫'
就是 '我叫小猫'
15. 模板字符串
模板字符串语法:使用反引号 `` ,内容拼接变量时,用 ${ } 包住变量。
在没有模板字符串之前,要拼接变量比较麻烦:'我的名字是' + name + '今年' + age + '岁了';
现在,使用模板字符串:`我的名字是${name},今年${age}岁了`;
,效果一样,但模板字符串更加简便。
注意:在模板字符串內,一定要注意语法的拼写正确!不能多空格或少空格。
26. 三元运算符
语法:条件 ? 满足条件执行的代码 : 不满足条件执行的代码;
符号: ? 与 : 配合使用
一般用来取值,例如:let a = 1 > 9 ? 1 : 9;
,如果为真,返回1,如果为假,返回9,很明显,1大于9是错的,为假,所以返回9。
还可以写字符串、js语句等,1 > 9 ? '1最大' : '错了,9最大';
结果为:'错了,9最大'
。
43. 数组
新增 push()
arr.push(元素1,元素2....)
push() 方法将一个或多个元素追加到数组的末尾,并返回该数组的新长度。
新增 unshift()
arr.unshift(元素1,元素2....)
unshift() 方法与push() 一样,不同之处是在开头追加,同样返回新数组的长度。
删除 pop()
arr.pop()
pop() 方法删除数组中最后一个元素,并返回该元素的值
删除 shift()
arr.shift()
shift() 方法删除数组中开头的一个元素,并返回该元素的值
删除 splice()
arr.splice(start, deleteCount)
起始位置,删除几个元素。如果第二个参数不写,就默认从指定的起始位置删除到最后。
49. 函数
函数可以实现代码复用,提高开发效率。
函数是什么?function执行特定任务的代码块。
函数的声明:
function 函数名(){
函数体
}
函数的命名规范:和变量命名基本一致,尽量使用小驼峰式命名,前缀尽量为动词,比如getMax()。例如:can是否可以执行某动作、has判断是否含有某值、is是否为某值、get获取某值、set设置某值、load加载某些数据。
函数调用:函数名()
参数:形参与实参(形式上的参数、实际上的参数)
function getSum(n, m){ //形参
let sum = n + m;
console.log(sum)
};
getSum(9,1); // 实参
函数的返回值:return 数据;
function fn(){
return 20
}; //相当于 fn() = 20,就是 20 这个值,给fn()了
let re = fn(); //调用 fn函数,把返回值给re
console.log(re); //20
注意:
1.在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用。
2.return 后面的代码不会被执行,会立即结束当前函数,所以 return 后面的数据不要换行写。
3.函数没有写 return ,返回结果就是 undefined 。
56. 作用域
分为 全局作用域、局部作用域。
全局作用域:整个 script 标签内部或独立的一个 js 文件。
局部作用域:函数内的代码环境,就是局部作用域,也称为函数作用域。
根据作用域的不同,变量可以分为:
全局变量:函数外部 let 的变量。全局变量在任何区域都可以访问和修改。
局部变量:函数內部 let 的变量。局部变量只能在当前函数內部访问和修改。
变量的访问规则:先局部,局部没有就找全局。
58. 匿名函数
函数分为:具名函数、匿名函数。
// 1. 具名函数
function fn(){ } //声明
fn() //调用
// 2. 匿名函数
function(){ } //声明
匿名函数,没有名字的函数,无法直接使用。
使用方式:
1. 函数表达式
将匿名函数赋值给一个变量,并且通过变量名称调用。
语法:let fn = function() { };
这个变量 fn 里面装的就是 function() { },console.log(fn)
输出显示 function(){ }
。
1.1 具名函数的调用可以写到任何位置
fun() // 111
function fun(){
console.log(111);
};
fun() // 111
而匿名函数,函数表达式只能写到后面:
1.2 函数表达式,必须先写表达式,后调用。
fun() // 报错,因为 let fun 的 let,变量必须先声明后使用
let fun = function(){
console.log(111);
};
fun() // 111
2. 立即执行函数
可以避免全局变量之间的污染。防止变量污染。
语法:
// 方式一 (函数(){}) ()
(function () {
...
}) ();
// 方式二 (函数(){} ())
(function () {
...
}() );
无需调用,立即执行,其实本质已经调用了。
多个立即执行函数之间用分号隔开;。
61. 逻辑中断
与 && 、或 || 、非 !
and or not
与 &&:一假则假,两真为真。两边都为 true 结果才为 true。
或 || :一真则真,全假为假。两边有一个是 true 就为 true。
非 ! :取反,假为真,真为假。 true变false,fasle变true。
短路:
短路只存在于 && || 中,当满足一定条件,就会让右边的代码不执行(短路)。
&& 左边为false就短路。
|| 左边为true就短路。
原因:左边的式子有结果,那么就没必要判断右边了。
false && age++ //与,一假全假,不执行后面的语句。(前面是假就短路了)
true || age++ //或,一真则真,不执行。(前面是真就短路了)
11 && 22 //都是真,一二都为真,返回最后一个值
11 || 22 //都是真,一真就行了,返回第一个值
62. 转换布尔型
true 、 false
例如:Boolean(111) 为 true
记忆:'' 、 0、undefined、null、false、NaN 转换布尔值后都是 false,其余的都是 true。
隐式转换:
1. 数字和字符串相加,就是拼接,结果是字符串。
2. 减法,只能用于数字,'2'-2,字符串'2'被转换数字型2,就是 2-2,等于 0。它会使空字符串""转换为0,''-2得-2
3. null 经过数字转换之后会变为 0。
4. undefined 经过数字转换之后会变为 NaN。
64. 对象
一种无序的数据集合,属性名:属性值,方法名:函数,键值对的形式。
let obj = {
uname: '猫',
id: '123',
color: '黒色',
'country-name': 'UK',
// 方法
SayHi: function() {
console.log("hi");
}
};
查:对象名.属性名
或 对象名['属性名']
。当属性名为字符串时,比如上面的'country-name' ,操作语法为:obj['country-name']
改:对象名.属性名 = 新值
增:对象名.新属性名 = 新值
,添加属性,写一个新的属性名(没有的)并赋值,就新增了
删:delete 对象名.属性
注意:. 点后面属性名不一定加引号,中括号 [] 里面的属性名一定加引号。
对象中的方法
let person = {
name: 'nnnnn',
sayHi: function() {
console.log("hi");
}
};
// 对象名.方法名() 调用
person.sayHi()
遍历对象
for in 语法可以遍历数组和对象。推荐使用 for in 遍历对象。
语法:
// for in 遍历对象【推荐】
let my_obj = {
id: 1001,
name: '鲤鱼',
date: '2023年2月19日14:04:25'
};
for (let k in my_obj){
console.log(k); //属性名 字符串格式的 'id' 'name' 'date'
//console.log(my_obj.k); 因为 k 里面是 带引号的属性名 是字符串格式的
// 相当于 (my_obj.'id')
//正确写法: (my_obj['id'])
console.log(my_obj[k]);
};
for in 遍历数组
// for in 遍历数组【不推荐遍历数组】
let arr = ['red','pink','blue'];
for (let k in arr){
console.log(k); //数组的下标 索引号,返回的是字符串类型的 '0','1','2'...
console.log(arr[k]); //遍历数组
};
70.内置对象
JavaScript内部提供的对象,是已经内置好的方法。
比如:console.log() 都是内置的方法。
1. 数学对象 Math
Math 对象包含的方法有:
random:生成 0-1 之间的随机数(包含0不包括1)
ceil:向上取整 1.1、1.5、1.9 》 2
floor:向下取整 写字符串只取前面一个数字 1.1、1.5、1.9 》 1 ‘12px' 》 1
round:四舍五入 -1.5 -1.51 》 -1 -2
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值
取整函数 parseint 与 取整 floor 区别:
parseInt(1.2); //1
parseInt('12px'); //12
Math.floor('12px'); // 1
2. 随机数函数 Math.random()
//分析:
Math.random() * 10; // 得到的是 0~9.99999.. 之间的
Math.random() * 11; // 得到的是 0~10.99999.. 之间的
Math.floor(10.999); // 向下取整,就是 10 了
//所以,想要获取0-10的随机数包含0和10的,直接random() * 11,再向下取整.
// 生成 0-10 的随机数
let n = Math.floor( Math.random() * (10+1) );
console.log(n);
// 5-10
Math.floor( Math.random() * (5+1) + 5);
// N-M 之间的随机数
Math.floor( Math.random() * (M - N + 1) + N);
随机颜色:
随机颜色
<h1>随机颜色 rbg</h1>
<h2>true 返回 rgb的,false 返回 16进制的</h2>
<script>
const h1 = document.querySelector('h1');
function my_color(flag) {
if(flag){
let n = function() {
return Math.floor( Math.random() * 256 );
};
return `rgb(${n()},${n()},${n()})`;
} else {
let str = '#';
let arr = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
for (let i = 1;i <= 6; i++){
// 下标随机数,arr.length数组长度16,索引号最大15
let random = Math.floor(Math.random() * arr.length);
str += arr[random];
};
return str;
};
};
h1.style.color = my_color(true);
</script>
78. 变量声明 const 优先
结论:
1. 优先使用 const ,如果后面要被修改就用 let 。
2. 建议数组和对象使用 const 来声明,const声明的对象可以修改里面的属性,因为对象是引用类型,里面存放的是地址,只要地址不变,就不会报错。
3. 简单数据类型使用 let ,引用数据类型的地址发生变化的时候也可以使用 let。简单数据类型,比如 for循环的 i++,需要 let i。
相对于简单数据类型,只要值有变化,要重新赋值,就要用 let ,基本数据类型在内存的栈里面。
复杂数据类型(引用数据类型)obj 对象,arr数组,都可以使用 let,可以修改里面的数据,因为复杂数据类型存放在内存的堆里面,而放在栈里面的是它的地址。
例如:修改arr数组,给数组追加一个元素blue,因为数组是复杂数据类型,数组在堆里面,在栈里的是它的地址,不管怎么追加,都不会修改栈里的地址,地址没变过,就不会报错。如果给 arr 数组重新赋值新数组,就会报错,arr = [1,2,3]
,这个新数组[1,2,3] 给了arr,在内存中开辟了新的空间,arr 的地址也是新的,对象做了改变,就错误了。
对象里只是添加删除某些元素,都是修改堆里面的数据,arr指向栈的地址不变,是可以的。数组和对象都可以。
栈:存放简单数据类型
堆:复杂数据类型存放在堆里面,而地址存放在栈里面
简单数据类型:num -- 》 栈 --》10
复杂数据类型:obj --》栈 --》地址0x112233 --》堆 --》{age:18}
二、Web APIs
分为:DOM 、 BOM
DOM,文档对象模型,主要操作网页内容,页面文档的内容。
BOM,浏览器对象模型,主要操作浏览器内容。
79. DOM 对象
DOM树,体现了标签与标签之间的关系。
DOM对象,页面所有标签元素都是DOM对象。比如获取到 <div> 标签,在浏览器打印出来,是对象类型的,typeof div ,object。
DOM对象:浏览器根据 html 标签生成的 JS对象。所有的标签属性都可以在中国对象上面找到,修改这个对象的属性会自动映射到标签身上。
DOM的核心思想,把网页内容当作对象来处理。
document 对象:是 DOM 里提供的一个对象,它提供的属性和方法都是用来访问和操作网页内容的,网页所有内容都在 document 里面。
80. 获取 DOM 元素
1. 选择匹配的第一个元素
语法:document.querySelector('css选择器');
使用:
const p = document.querySelector('div');
console.log( p );
参数:css选择器(字符串类型的)。
参数是 css选择器 的!字符串格式!css怎么用这就怎么用,[ ]属性选择器也可以用!!
如果没有匹配到,就返回 null 。
2. 选择匹配的所有元素
语法:document.querySelectorAll('css选择器');
使用:
const p = document.querySelectorAll('div');
console.log( p[0] ); // p[索引号]
返回一个 NodeList 对象集合 伪数组,有长度有索引号的数组,但是没有数组的方法。
3. 【其他获取方法】
// 根据 id 获取一个元素
document.getElementById('nav');
// 根据 标签 获取一类元素
document.getElementsByTagName('div');
// 根据 类名 获取元素
document.getElementsByClassName('w');
81. 修改对象元素内容
修改标签元素里面的内容。
innerText 不支持识别html标签,innerHtml 解析标签。
1. 对象.innerText 属性
查看元素内容:div.innerText
修改元素内容:div.innerText = '内容'
2. 对象.innerHtml 属性
查看元素内容:div.innerHtml
修改元素内容:div.innerHtml = '<div>支持html标签</div>'
82. 修改元素常用属性
通过 js 设置修改标签元素属性,比如通过 src 修改图片。
常见的属性:href、title、src 等等。
语法:对象.属性名 = 属性值;
// HTML的 <img src='bg01.jpg'>
// 1. 获取元素
const pic = document.querySelector('img');
// 2. 操作元素 更改图片地址
pic.src = 'bg02.jpg';
例如做随机壁纸:
function getRandom(n,m){
return Math.floor(Math.random() * (m - n + 1)) + n
};
// 1. 获取图片对象
const img = document.querySelector('img');
// 2. 随机得到序号
const random = getRandom(1,6);
// 3. 更换路径
img.src = `./images/bg${random}.jpg`
83. 修改元素样式属性
1. 通过 style 属性操作 CSS
语法:对象.style.样式属性 = 值
属性有连接符的,(background-color),使用小驼峰法。赋值的时候,需要加css单位,例如 px。
例如:
div.style.width = '300px'; //修改了div的宽度。
div.style.backgroundColor = '#f00'; //属性有连接符的,(background-color),使用小驼峰法
2. 操作类名 className 操作CSS
如果修改的样式比较多,直接通过修改style属性比较繁琐。可以通过修改 css 类名的形式来设置样式。
语法:元素.className = '类名'
注意:
1. 由于 class 是关键字,所以使用 className 去代替。
2. className 是使用新值 换 旧值,会覆盖的原来的类名,如果需要添加一个类,需要保留之前的类名。
3. classList 操作类控制CSS
为了解决className 容易覆盖之前的类名,可以通过 classList 来追加、删除、切换类名
语法:
追加一个类 : 元素.classList.add('类名');
删除一个类 : 元素.classList.remove('类名');
切换一个类 : 元素.classList.toggle('类名');
,有就删除,没有就追加。
88. 操作表单元素属性
修改表单属性,比如显示密码,本质就是把表单类型转换为文本框。
获取:DOM对象.属性名
设置:DOM对象.属性名 = 新值
例如,表单.value = '用户名'、表单.type = 'password'。
89. H5自定义属性 data-
在html5中推出来的专门的 data-自定义属性,在标签里一律以 data- 开头,在DOM对象上一律以 dataset 对象方式获取。
语法:data-自定义
,获取: dataset.自定义
例如:
<div id="bg" data-id="1" data-name="《Umamuseme》游戏壁纸"></div> <!-- 这个div已经有id了,但我想给它自定义id数字、自定义名字-->
<script>
const box = document.querySelector('div');
console.log(box.dataset)
console.log(box.dataset.id) //获取 data-id 的值
console.log(box.dataset.name) //获取 data-name 的值
</script>
90. 定时器
语法:setInterval( 函数, 间隔时间 );
也可以调用函数,setInterval( 函数名, 间隔时间 );
关闭定时器:
let 变量名 = setInterval(函数, 间隔时间)
clearInterval(变量名); // 关闭定时器
93. 事件监听
语法:元素对象.addEventListener('事件类型' , 要执行的函数 , 是否使用捕获);
语法2:事件源.on事件 = function(){}; // on方式会被覆盖,不推荐使用。
事件元素:事件源,要获取dom元素
事件类型:用什么方式触发,比如鼠标单击 click 、鼠标经过 mouseover 等
事件调用的函数:要做什么事。
是否使用捕获:写 true 是,不写或写false就是冒泡。
区别: on方式会被覆盖,addEventListener方式可以绑定多次,拥有多样性,推荐使用。
事件类型:
鼠标事件:click 点击、mouseenter 经过、mouseleave离开
焦点事件:focus 获得焦点、blur 失去焦点
键盘事件:Keydown 按下触发、Keyup 抬起触发
文本事件: input 输入事件
100. 事件对象 event
事件对象,是个对象,这个对象里面有事件触发时的相关信息。
例如鼠标点击事件后,事件对象就存了鼠标点在哪个位置等信息。
使用场景:判断用户按下哪个键,比如按下回车就发送评论....
语法:在事件绑定的回调函数的第一个参数就是事件对象,一般命名为 event、ev、e。 元素.addEventListener('click' , function(e) {})
,这个 e 就是事件对象。
event.target
:指的是真正触发事件的那个元素。用户的鼠标点击在那个标签上 e.target 就来自哪里。比如获取 a 标签元素。
event.currentTarget
: 指的是绑定了事件监听的元素(可以理解为触发事件元素的父级元素)。用户的鼠标不管点击在哪个标签上 e.currentTarget始终是在所绑定的标签事件发出
event.target.tagName
:tagName 属性返回元素的标签名。返回值始终是大写的。
102. 环境对象 this 、回调函数
this :谁调用,this 就是谁。
div.onclick = function() {
this.style.width = '100px'; // this 就是 div
}
回调函数:把函数 A 作为参数传递给函数 B 时,这个函数 A 就称为回调函数。
举例:
function fun() {
console.log('我是回调函数');
};
// 把 fun 传递给 setInterval,fun就是回调函数
setInterval(fun, 1000);
105. 事件流
捕获阶段:document - html - body - div
冒泡阶段:div - body - html - document
事件捕获:
从DOM的根元素开始去执行对应的事件(从外到里)
a.addEventListener('click',function() {
console.log('爷爷');
});
b.addEventListener('click',function() {
console.log('父');
});
c.addEventListener('click',function() {
console.log('子');
});
点击 c 时,触发顺序是 a - b - c 。
addEventListener 第三个参数传入 true,就代表是捕获阶段触发(很少使用)。
事件冒泡:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次触发。简单理解就是,当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件。
事件冒泡是默认存在的。
addEventListener 第三个参数是 false,或者默认都是冒泡。
a.addEventListener('click',function() {
console.log('爷爷');
});
b.addEventListener('click',function() {
console.log('父');
});
c.addEventListener('click',function() {
console.log('子');
});
c 触发事件,会依次 c - b - a 的触发事件。
阻止事件传播:
语法:事件对象.stopPropagation()
此方法可以阻断事件流动传播,可以阻断 捕获阶段 和 冒泡阶段 。
109. 阻止元素默认行为
我们某些情况下需要阻止默认行为,比如阻止,a链接的跳转,表单域跳转(点击提交后跳转),表单未填满就提交注册。
语法:e.preventDefault( );
const a = document.querySelector('a');
// 阻止默认行为 不让点击a后跳转
a.addEventListener('click',function(e) {
e.preventDefault()
})
110. 页面加载 load、滚动事件 scroll
1. 页面加载事件 load
事件名:load
监听页面所有资源加载完毕,也可以针对某个资源绑定load事件。
window.addEvenListener('load',function() {} );
//监听页面所有资源加载完毕。
2. 页面加载事件 DOMContentLoaded
事件名:DOMContentLoaded
监听页面DOM加载完毕,无需等待样式表、图片等资源加载,只要DOM加载完就触发。
document.addEventListener('DOMContentLoaded', function() { })
3. 页面滚动事件 scroll
事件名:scroll
监听整个页面滚动:
window.addEvenListener('scroll',function() {} );
//监听页面滚动。
4. 页面滚动事件-获取位置 scrollLeft、scrollTop、scrollWidth、scrollHeight
scrollLeft:元素距离页面左侧的距离。可读写。
scrollTop:元素距离页面顶部的距离。可读写。
scrollWidth:页面宽度
scrollHeight:页面高度
5. 页面滚动事件-滚动到指定的坐标 scrollTo(x,y)
scrollTo() 方法可用把内容滚动到指定的坐标。
语法:元素.scrollTo(x,y)
window.scrollTo(0,1000);
,让页面滚动到 y 轴 1000像素的位置,(类似于css锚点,但css锚点不用测距离)
112. 页面尺寸事件 client、offset
1. resize 事件
会在窗口尺寸改变的时候触发事件
window.addEventListener('resize',function() {
// 执行的代码
})
2. clientWidth、clientHeight 获取宽高
获取元素的可见部分宽高(不包含边框,margin,滚动条等)
clientWidth:获取元素宽度。
clientHeight:获取元素高度。
获取出来的数值是数字型,不带px单位。是只读属性。如果盒子隐藏,获取的结果是0。
3. offsetWidth、offsetHeight 获取宽高,offsetLeft、offsetTop 获取位置
获取宽高:
offsetWidth、offsetHeight。
获取元素的自身可视宽高、包含元素自身设置的宽高、padding、border。
获取出来的数值是数字型,不带px单位。是只读属性。如果盒子隐藏,获取的结果是0。
获取位置:
offsetLeft、offsetTop。
获取元素距离自己定位父级元素的左、上距离。(最近的一个带有定位的父级)
offsetLeft、offsetTop 是只读属性。
4. element.getBoundingClientRect() 获取元素的大小及位置坐标。
element.getBoundingClientRect() 会返回一个对象,有元素的宽、高、上下左右四个位置、xy坐标。
113. scroll、client、offset 总结