先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
正文
- 模块化
这些新特性可以在现代浏览器中直接使用,或者通过转换工具(如Babel)将ES6代码转换为ES5代码以支持旧版本的浏览器。
块级作用域
在 ES6 之,JavaScript中只有函数作用域和全局作用域,而在 ES6 引入了块级作用域,使得我们可以在代码块中声明变量,而不必担心变量污染全局作用域。
变量的作用域范围
函数作用域: 在函数内部声明的变量只能影响到变量所在的函数体内,无法从外部对函数内部的变量进行调用,被称为"函数作用域",变量在定义的环境(函数)中及嵌套的子函数中处处可用。
块级作用域: {} 这个花括号里面的作用域就是块级作用域。 外层作用域无法获取内层作用域
var 声明的变量是函数作用域
function foo() {
var flag = true;
if(flag) {
var a = ‘abc’;
let b = ‘ABC’;
console.log(a); // 输出abc
console.log(b); // 输出ABC
}
console.log(a); // 输出abc
console.log(b); // 报错
}
foo();
变量在定义的环境(函数)中以及嵌套的子函数中处处可用
var i = 100
for(var i=0; i<5; i++){
console.log(i) //1,2,3,4
}
console.log(i) //5
var的话就会导致在 for 循环的变量 i 覆盖掉循环之前的变量i,所以我们需要一块私有领域来包裹住for里面产生的变量,所以产生了块级作用域。
let 声明的变量是块级作用域
用let命令新增了块级作用域,使外层作用域无法获取内层作用域,使变量更安全,但是会造成暂时性死区
// 块级作用域: 外层作用域无法获取内层作用域
function a(){
let a=100;
if(a==100){
let a=300
console.log(a) //300
}
console.log(a) //100
}
a()
const常量:
const PI = 3.1415;
PI = 3.1415926; // 报错
var、let和const的区别
- var 声明的变量会提升到作用域的顶部,而 let 和 const 不会进行提升
- var 声明的全局变量会被挂载到全局 window 对象上,而 let 和 const 不会
- var 可以重复声明同一个变量,而 let 和 const 不会
- var 声明的变量作用域范围是函数作用域,而 let 和 const 声明的变量作用域范围是块级作用域。
- const 声明的常量,一旦声明则不能再次赋值,再次赋值会报错(更改对象属性不会,因为对象地址没有变)
作用域提升:
在代码预编译时,javaScript 引擎会自动将 var 声明的语句提升到当前作用域的顶端,。
var声明的变量会提升到作用域的顶部, var可以在声明前调用,值默认为undefined
console.log(a); // 输出undefined
console.log(b); // 报错
console.log(PI); // 报错
var a = ‘abc’;
let b = ‘ABC’;
const PI = 3.1415;
挂载到全局变量:
全局环境下绑定的就是全局对象,浏览器下是window,node下是global。
var在全局作用域声明变量时会创建一个新的全局变量作为全局对象的属性 。var在全局声明变量时会被挂载到 window 对象上,可以使用window. 的形式访问该变量,或者直接使用变量名的方式。
如果省略变量前面的 let 或者 var 则该变量会成为一个全局变量
var varInfo = ‘var 在声明变量’
let letInfo = ‘let 在声明变量’
const PI = 3.1415;
// 定义函数,测试两个变量是否在函数体外部可以使用
function test(){
// 在函数作用域中声明的变量 在函数执行退出时立刻销毁
var msg = ‘这是局部变量’
// 没有用 var、let 声明的变量会被挂载到全局
message = ‘这是全局变量’
}
test()
// 在全局作用域下声明的变量
console.log(varInfo) // var 在声明变量
console.log(window.varInfo) //var 在声明变量
console.log(letInfo) //let 在声明变量
console.log(window.letInfo) // undefined
console.log(window.PI); // undefined
// 在函数作用域下 声明的变量
console.log(window.message) //这是全局变量
console.log(message) //这是全局变量
console.log(msg) // 报错 es6.html:33 Uncaught ReferenceError: msg is not defined 不能访问函数内部的变量
通过以上案例我们可以发现几点:
- 在全局作用域下 var 声明的变量会被挂载到 window 上,而 let、 const不会。
- 在函数中声明的变量只在函数中生效(函数作用域),当函数执行退出时变量也随即被销毁,因此不能访问函数内部的变量,而在函数内部可以访问函数外部的全局作用域中的变量。(作用域链)
- 没有被声明的变量会被挂载到 window 上。
重复声明变量:
var a = ‘abc’;
var a;
console.log(a); // 输出abc
let b = ‘ABC’;
let b;// 报错
对象的扩展
对象字面量的扩展
- 属性初始值的简写
- 对象方法的简写: 消除了冒号和 function 关键字。
- 可计算属性名:在定义对象时,对象的属性值可通过变量来计算 [ ]。
const name = ‘why’
const firstName = ‘first name’
const person = {
name,
[firstName]: ‘ABC’,
sayName () {
console.log(this.name)
}
}
对象的新增方法
Object.is
通过 Object.is 来判断是否为同一个对象
console.log(+0 === -0) // true
console.log(Object.is(+0, -0)) // false
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true
Object.assign
一个对象接受来自另一个对象的属性和方法。 后者源对象 会覆盖目标对象中已有的同名属性 Object.assign方法不能复制属性的 get 和 set。
const person1 = {
age: 23,
name: ‘why’
}
const person2 = {
age: 32,
address: ‘广东广州’
}
const person3 = Object.assign({}, person1, person2)
console.log(person3) // { age: 32, name: ‘why’, address: ‘广东广州’ }
Object.keys
返回一个由一个给定对象的自身可枚举属性组成的数组
Object.values
返回一个由一个给定对象的自身可枚举属性值组成的数组. 甚至 Object.values用于扁平化数组例如:
const obbj = {
‘a’:[2,4,6],
‘b’:[1,2,4,23],
‘c’:[32,43,54],
‘d’:[4,56,20],
}
let merge = Object.values(deps).flat(Infinity);
其中使用Infinity
作为flat
的参数,使得无需知道被扁平化的数组的维度。
方法
方法仅仅是一个具有功能而非数据的对象属性。将方法定义为一个函数,它会有一个内部[[HomeObject]]属性来容纳这个方法从属的对象。
const person = {
// 是方法 [[HomeObject]] = person
sayHello () {
return ‘Hello’
}
}
// 不是方法
function sayBye () {
return ‘goodbye’
}
const friend = {
sayHello () {
return super.sayHello() + ‘!!!’
}
}
Object.setPrototypeOf(friend, person)
console.log(friend.sayHello()) // Hello!!!
friend.sayHello()
方法的[[HomeObject]]
属性值为friend
。friend
的原型是person
。super.sayHello()
相当于person.sayHello.call(this)
。
箭头函数
ES6 中引入了箭头函数,它是一种更加简洁的函数定义方式,在箭头函数中没有属于自己的 this 和arguments 对象,他们会从外部作用域继承 this 和 arguments。
const add = (a+b)=> a+b
箭头函数的定义方式更加简洁
模板字符串
模板字符串,它是一种更加灵活的字符串定义方式。模板字符串使用反引号()包裹字符串,可以在字符串中插入变量和表达式。
const age =18;
const message = My name is ${name}, and I am ${age} years old.;
console.log(message);//输出:My name is Alice, and I am 18 years old.
在上面的代码中,使用模板字符串定义了一个字符串变量message,并在其中插入了变量name和age的值。
在${}
中甚至可以放入任意的JavaScript表达式,进行运算,以及引用对象属性。
const name = ‘lili’;
const score = 80;
const result = ${name}的考试成绩${score > 60?'':'不'}及格
[] 结合模板字符串实现动态取值
对象的取值除了用 .
意外还可可以使用 []
访问动态属性名。
let obj = {
title1: ‘嘻嘻嘻’,
title2: ‘啦啦啦’
}
const number = 2
let name = obj[title${number}
]
也可以通过[]
为对象动态添加属性
cosnt index = 5
obj[title${index}
] = ‘哈哈哈’;
解构
解构是一种更加方便的变量赋值方式。解构赋值可以从数组或对象中提取值,并将其赋值给变量。
对象解构
必须为解构赋值提供初始化程序,同时如果解构 null 或者 undefined ,解构会发生错误。
const person = {
name: ‘AAA’,
age: 23
}
const { name, age } = person
console.log(name) // AAA
console.log(age) // 23
解构赋值
const person = {
name: ‘AAA’,
age: 23
}
let name, age
// 必须添加(),因为如果不加,{}代表是一个代码块,而语法规定代码块不能出现在赋值语句的左侧。
({ name, age } = person)
console.log(name) // AAA
console.log(age) // 23
解构默认值
使用解构赋值表达式时,如果指定的局部变量名称在对象中不存在,那么这个局部变量会被赋值为undefined,此时可以随意指定一个默认值。
const person = {
name: ‘AAA’,
age: 23
}
let { name, age, sex = ‘男’ } = person
// 同名 赋值 等价于
let {name:name,age:age,sex =‘男’ } = person
console.log(sex) // 男
let { name: name, age: age } = person含义是:在person对象中取键为name和age的值,并分别赋值给name变量和age变量。
非同名赋值
const person = {
name: ‘AAA’,
age: 23
}
let { name: newName, age: newAge } = person
console.log(newName) // AAA
console.log(newAge) // 23
// 在 vue 中的应用
const { params, query } = this.$route
// 解构data, 重命名为res
const { data: res } = await axios.get(‘/api’)
嵌套对象解构
const person = {
name: ‘AAA’,
age: 23,
job: {
name: ‘FE’,
salary: 1000
},
department: {
group: {
number: 1000,
isMain: true
}
}
}
// 在person中提取键为job、在person的嵌套对象department中提取键为group的值,并把其赋值给对应的变量。
let { job, department: { group } } = person
console.log(job) // { name: ‘FE’, salary: 1000 }
console.log(group) // { number: 1000, isMain: true }
注意解构的对象不能为 undefined
、null
。否则会报错,所以我们要给被解构的对象一个默认值避免报错的发生。
const {a,b,c,d,e} = obj || {};
数组解构
使用数组字面量,且解构操作全部在数组内完成,解构的过程是按值在数组中的位置进行提取的。
const colors = [‘red’, ‘green’, ‘blue’]
let [firstColor, secondColor] = colors
// 按需解构
let [,threeColor] = colors
console.log(firstColor) // red
console.log(secondColor) // green
console.log(threeColor) // blue
交换变量
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
嵌套数组
const colors = [‘red’, [‘green’, ‘lightgreen’], ‘blue’]
const [firstColor, [secondColor]] = colors
console.log(firstColor) // red
console.log(secondColor) // green
解构数组中的不定元素的原理能实现数组的复制
const colors = [‘red’, ‘green’, ‘blue’]
const concatColors = colors.concat()
const […restColors] = colors
console.log(concatColors) // [‘red’, ‘green’, ‘blue’]
console.log(restColors) // [‘red’, ‘green’, ‘blue’]
es6 中的运算符(??、??=、?.、?:)
?? 非空运算符
?? 运算符也被称为空值合并操作符。
如果第一个参数为 null 或 undefined 则返回第二个参数,否则返回第一个参数。
null ?? 8 // => 8
undefined || 8 // =>8
6 ?? 8 // => 6
0 ?? 8 // => 0
false ?? 8 // => false
‘’ ?? 8 // => ‘’
function(obj){
var a = obj ?? {}
}
等价于
function(obj){
var a;
if( obj === null || obj === undefined){
a = {}
} else {
a = obj;
}
}
而 || 运算符则是 判断两个值之间的关系,如果其中一个值为真,则返回该值,否则返回另一个值。若左侧操作数为假值时返回右侧操作数。
null || 8 // => 8
undefined || 8 // =>8
6 || 8 // => 6
0 || 8 // => 8
false || 8 //=> 8
‘’ || 8 // => 8
function(obj){
var a = obj || {}
}
等价于
function(obj){
var a;
if(obj === 0 ||
obj === “” ||
obj === false ||
obj === null ||
obj === undefined){
a = {}
} else {
a = obj;
}
}
js 中的假值包含:未定义 undefined、空对象 null、数值 0、 NaN、布尔 false,空字符串’'。
?? 运算符允许我们在忽略错误值(如 0 和空字符串)的同时指定默认值。
??= 空赋值运算符
??= 被称为空赋值运算符,与 ?? 运算符相似仅在左值为 null / undefined 时对其赋值。
var a = null
var b = 8
console.log(a ??= b) // => 8
相当于
console.log(a = (a ?? b)) // => 8
let c = 0;
c ??= b;
console.log©; // 0
a 的值为 null 或 undefined 时,则将 b 的值赋给a变量,否则 a 保持变量原有的值不变。
仅当值为 null 或 undefined 时,此赋值运算符才会赋值。
?. 可选链操作符
Vue 编码基础
2.1.1. 组件规范
2.1.2. 模板中使用简单的表达式
2.1.3 指令都使用缩写形式
2.1.4 标签顺序保持一致
2.1.5 必须为 v-for 设置键值 key
2.1.6 v-show 与 v-if 选择
2.1.7 script 标签内部结构顺序
2.1.8 Vue Router 规范
Vue 项目目录规范
2.2.1 基础
2.2.2 使用 Vue-cli 脚手架
2.2.3 目录说明
2.2.4注释说明
2.2.5 其他
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
有的值不变。
仅当值为 null 或 undefined 时,此赋值运算符才会赋值。
?. 可选链操作符
Vue 编码基础
2.1.1. 组件规范
2.1.2. 模板中使用简单的表达式
2.1.3 指令都使用缩写形式
2.1.4 标签顺序保持一致
2.1.5 必须为 v-for 设置键值 key
2.1.6 v-show 与 v-if 选择
2.1.7 script 标签内部结构顺序
2.1.8 Vue Router 规范
Vue 项目目录规范
2.2.1 基础
2.2.2 使用 Vue-cli 脚手架
2.2.3 目录说明
2.2.4注释说明
2.2.5 其他
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-y7I6bS0y-1713664182470)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!