JavaScript笔记
写在前面:
这篇笔记是b站课程黑马前端JS课程的笔记,发到博客上供大家参考。整个一周学下来感觉,这套课程最大的缺点是不够系统化。为了实现课程案例,有时候会穿插讲一些知识点,稍不注意就会混淆学习的结构顺序。虽然能很快学习入门,但是作为全面的学习材料不够。在这里我提供以下的补充,大家一定要在听课的过程中总结出自己对于JS的框架,不然很容易云里雾里:
- MDN文档:用于在学习过程中补充
- ES6入门教程:其实相对晦涩,但认真看完会很有收获
- JS菜鸟:仅做参考,其实还是MDN文档更实用
- 山月大佬博客:其实是在学习过程中偶然发现的,大佬记录了他的学习路线、面试经验等等,真的收获许多。
- 还有很多学习途径,大家不要吊死在一棵树上
Day 1(基础)
1. 组成:
ECMAScript(基础语法)、Web APIs(DOM、BOM)
2. 输出方法:
-
window.alert() 弹出警告框。
-
document.write() 将内容写到 HTML 文档中,如果加载完文件才执行方法会覆盖整个html。
-
innerHTML 写入到 HTML 元素。
eg.
document.getElementById(“demo”).innerHTML = “段落已修改。”;
- console.log() 写入到浏览器的控制台(调试)。
3. 变量定义:
- let:定义的变量只在let所在代码块有效(适合用在for循环)
- const:常量,初始时赋值
- var:全局有效(过时)
4. 模板字符串:
反引号包住 ’ ‘,允许在模板里运算:
const name = 'Runoob';
const age = 30;
const message = `My name is ${name} and I'm ${age} years old.`;
let price = 10;
let VAT = 0.25;
let total = `Total: ${(price * (1 + VAT)).toFixed(2)}`;
5. 类型转换
- 隐式转换
"+"两侧有一个是字符串,就会执行拼接,都变成字符串
但如果单用+‘123’,可以把字符串转化为数字型123
let num = +prompt("请输入数字")
- 显式转换
字符串化数字型
Number("3.14") // 返回 3.14 Number(" ") // 返回 0 Number("") // 返回 0 Number("99 88") // 返回 NaN parseFloat() //化浮点数 parseInt('1a')===1 //化整数,只化开头数字,
- boolean类型转换:
0和’'(空字符串)都是false
Day 2(基础)
1. 运算符和比较
=== 类型和值都相等
!==类型和值至少有一个不相等
2. 各类语句
3. 三元表达式
条件?真执行:假执行
4. 数组操作
- push添加到数组末尾
console.log(arr.push('第三个')) //返回数组操作后长度 3
- unshift添加到数组开头
arr.unshift('开头')
- pop、shift、splice
arr.pop() //删除最后一个且返回该元素
arr.shift() //删第一个并返回
arr.splice(start,deleteCount) //起始位置+删除个数,省略第二个参数则从起始位置删完数组
5. 函数
//定义
function funname(a,b){}
<body>
<p>本例调用的函数会执行一个计算,然后返回结果:</p>
<p id="demo"></p>
<script>
function myFunction(a,b){
return a*b;
}
document.getElementById("demo").innerHTML=myFunction(4,3);
</script>
</body>
- 函数默认返回值:undefined
- 匿名函数(函数表达式、立即执行函数)
let x = function (a, b) {return a * b}; //函数表达式
//立即执行函数减少全局变量之间污染
(function(){
console.log(10)
})(); //必须有分号,立即调用
//可以用=>写
(() => {
console.log('Welcome to the Internet.');
})();
//匿名函数做参数时用=>写法更简洁
// good
[1, 2, 3].map((x) => {
return x * x;
});
// best
[1, 2, 3].map(x => x * x);
6. 作用域
-
全局(在所有脚本和函数都能用)、局部(仅在函数内)
-
如果变量没有声明会自动变为全局变量
<p>
如果你的变量没有声明,它将自动成为全局变量:
</p>
<p id="demo"></p>
<script>
myFunction();
document.getElementById("demo").innerHTML =
"我可以显示 " + carName;
function myFunction()
{
carName = "Volvo"; //自动定义为全局变量
}
</script>
7. 对象
- 对象定义及方法
<p>创建和使用对象方法。</p>
<p>对象方法作为一个函数定义存储在对象属性中。</p>
<p id="demo"></p>
<script>
let person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() //定义函数,即对象方法
{
return this.firstName + " " + this.lastName;
}
};
document.getElementById("demo1").innerHTML = "不加括号输出函数表达式:" + person.fullName; //其实就是当字符串输出,无运算
document.getElementById("demo2").innerHTML = "加括号输出函数执行结果:" + person.fullName();
</script>
- 对象遍历
for(let k in person)
{
console.log(person[k]);
}
//函数返回键名(对象(不含继承)的所有可枚举属性)
Object.keys(obj)
//对象属性调用(两种方法)
person['name']
person.name
//对象数组遍历
-
内置对象(Math)
- Math.floor() 向下取整
- Math.random() 产生 [0-1) 之间任意数
随即生成n内的随机数
- Math.floor(Math.random()*n)
随机生成n-m之间的随机数
- Math.floor(Math.random()*(m-n+1))+n
8. 深拷贝与浅拷贝(数据存储)
数组和对象优先使用const
关于值的储存
- 简单数据、复杂数据类型:存在栈和堆中
- 栈存储地址,指向堆中的地址
Day 3(APIs:DOM)
1. DOM树、DOM对象
2. 获取DOM元素
-
通过’CSS选择器’获取:
- document.querySelector(‘CSS选择器’) 只选择匹配的第一个
- document.querySelectorALL(‘CSS选择器’) 选择全部
- 选择出来的对象数组无法增删,伪数组
-
get方法
var x=document.getElementById("intro"); //通过id查找
var x=document.getElementById("main");
var y=x.getElementsByTagName("p"); //标签名查找
var x=document.getElementsByClassName("intro"); //类名查找
3. 修改HTML内容
- innerHTML(识别标签)
<h1 id="header">旧标题</h1>
<script>
var element=document.getElementById("header");
element.innerHTML="<strong>新标题</strong>"; //会识别标签,标题加粗
</script>
- innerText(不解析标签,原封放入)
案例:修改年会抽签
4. 修改元素样式属性
- 通过style修改:
//修改某一元素样式
document.getElementById(id).style.property=新样式
//修改body,由于body唯一,所以不用查找
document.body.style.backgroundImage='新图片地址'
- 通过类名className修改:
const div = document.querySelector('div')
div.className = 'box'
//会覆盖类,所以要按顺序写类名
div.className = 'nav box'
- 通过classList修改:
box.classList.add('active') //增加
box.classList.remove('active') //删除
box.classList.toggle('active') //切换,有删无增
5. 修改表单属性
-
取表单值 .value
-
表单 .type :text\password
.checked .disabled .
6. H5自定义属性:data
const a = document.querySelector('div')
a.dataset //获取值,dataset
7. 定时器
- 间歇函数
setInterval(调用函数,间隔时间(ms)) //开启定时器,函数返回定时器id
let id = setInterval(调用函数,间隔时间) //开启间隔定时器,一定用let储存
clearInterval(id) //关闭定时器
- 延时函数(全局)
setTimeout(() => {
console.log("延迟了 1 秒。");
}, 1000);
案例:定时轮播图
Day 4 (APIs 事件)
1.事件(监听)
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型 (如 “click” 或 “mousedown”).
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
-
不同版本:
- HTML事件属性:在HTML中绑定事件+函数
<button onclick="displayDate()">点这里</button>
- HTML DOM 分配事件:事件+函数 对象分配
document.getElementById("myBtn").onclick=function(){displayDate()};
2. 事件类型
HTML DOM 事件对象 | 菜鸟教程 (runoob.com)
- 鼠标事件
- 焦点事件
- focus触发 blur失去焦点
- 键盘事件
- keydown keyup
- 文本事件
- input
- 页面加载事件
- 元素滚动事件
- scrolls
- 页面尺寸事件 (client offset)
3. 事件对象
element.addEventListener(event, function(e), useCapture);
//e是事件对象
4. 环境对象(this)
eg.案例tab切换
Day 5(APIs 事件)
1. 事件流(捕获冒泡)同名事件
- 阻止捕获、冒泡 stopPropagation()
2. 事件解绑
- on方式,赋值null
btn.onclick = null
- 解除监听函数
removeEventListener(type, listener,option);
一个字符串,表示需要移除的事件类型。
需要从目标事件移除的事件监听器函数。匿名函数无法解绑
options
可选
一个指定事件侦听器特征的可选对象。可选项有:
capture
: 一个布尔值,指定需要移除的事件监听器函数是否为捕获监听器。如果未指定此参数,默认值为false
。
3. 事件委托
- ==(原理)==利用冒泡特点:给父元素绑定事件,子元素冒泡触发事件
- 使用事件对象.target.tagName,获得触发的对象
4. 阻止元素默认行为
const checkbox = document.querySelector("#id-checkbox");
checkbox.addEventListener("click", checkboxClick, false);
function checkboxClick(event) {
let warn = "preventDefault() won't let you check this!<br>";
document.getElementById("output-box").innerHTML += warn;
event.preventDefault();
}//使用preventDefault()阻止点击事件执行
5. 实例化 (new)
- 示例:日期对象使用
6.DOM节点操作
- 节点操作
- 查找父节点、子节点、兄弟节点
- 增加节点 createElement() appendChild() insertbefore()
- 克隆节点 cloneNode(true) 布尔参数表示是否包含后代节点复制
- 删除节点 removeChild()
7. M端事件(了解)+ swiper插件
Day 6 (BOM)
1. JS执行机制:单线程
- 同步异步:异步通过回调函数实现
- 先执行同步任务,将异步任务放进任务队列,完成同步任务后依次序将异步任务放入执行栈中执行。
2. location对象
-
herf属性(跳转页面)
-
search属性(得到url ?后内容)
-
hash属性(得到url # 后内容)
-
reload方法 刷新页面 布尔参数表示强制刷新
3. nevigator对象
- userAgent 检测浏览器平台信息(切换pc端和手机端)
4. history对象
- back() 后退
- forward() 前进
- go(参数) 参数是1,前进一个页面,-1后退一个页面
5. 本地存储
- localStorage
localStorage.setItem("myCat", "Tom"); //增加 (键值,字符串)
let cat = localStorage.getItem("myCat");//读取
localStorage.removeItem("myCat"); //删除
localStorage.clear(); // 移除所有
- 存储复杂数据类型:使用JSON.stringify()转换为字符串,parse()还原为对象
localStorage.setItem("myCat",JSON.stringify(obj) ); //复杂数据类型要转换为JSON字符串 obj指对象
const cat = JSON.parse(localStorage.getItem("myCat"));//读取 记得要转换为对象
6. map() join() 方法
- map() 迭代数组:
创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
const array1 = [1, 4, 9, 16];
// 遍历旧数组,可以产生新数组
const map1 = array1.map((x) => x * 2);
console.log(map1);
// Expected output: Array [2, 8, 18, 32]
- join() : 将数组转化为字符串
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串,用逗号或指定的分隔符字符串分隔。
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());
// Expected output: "Fire,Air,Water"
Day 7 补充语法
1. 正则表达式
- 创建正则表达式:
//使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:
const re = /ab+c/;
//或者调用RegExp对象的构造函数,如下所示:
const re = new RegExp("ab+c");
-
使用正则表达式:参考文档
-
元字符
-
边界符(开头结尾)精确匹配,一个字符
-
量词(出现次数)
*
匹配前一个表达式 0 次或多次。等价于 {0,}
。例如,/bo*/
会匹配 “A ghost boooooed” 中的 ‘booooo’ 和 “A bird warbled” 中的 ‘b’,但是在 “A goat grunted” 中不会匹配任何内容。+
匹配前面一个表达式 1 次或者多次。等价于 {1,}
。例如,/a+/
会匹配 “candy” 中的 ‘a’ 和 “caaaaaaandy” 中所有的 ‘a’,但是在 “cndy” 中不会匹配任何内容。?
匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}
。例如,/e?le?/
匹配 “angel” 中的 ‘el’、“angle” 中的 ‘le’ 以及 "oslo’ 中的 ‘l’。如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。例如,对 “123abc” 使用/\d+/
将会匹配 “123”,而使用/\d+?/
则只会匹配到 “1”。还用于先行断言中,如本表的x(?=y)
和x(?!y)
条目所述。 -
还用于先行断言中,如本表的 x(?=y)
和 x(?!y)
条目所述。 |