36、 ES6 中常用的新特性
在这里列举几个常用的:
- 类
- 模块化
- 箭头函数
- 函数参数默认值
- 模板字符串
- 解构赋值
- 延展操作符
- 对象属性简写
- Promise
- Let与Const
1.类(class)
JS里的类就是构造函数的语法糖。
基本用法
- 类里面有个constructor函数,可以接收传递过来的参数,同时返回实例对象
- constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,类也会自动生成这个函数
- 公共属性放在constructor中,公共方法直接在类里面写函数声明,会自动添加至原型对象中
- class类没有变量提升,所以必须先定义类,才能通过类实例化对象
- super()调用父类里的constructor方法,可以向里面传参,就等于Father.call(this,x,y),super 必须在子类的this前面调用
- class里面的方法的this指向的是调用者,如果调用者不是类的实例,就需要改变this的指向
2.模块化(Module)
模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。
js
export var name = 'Rainbow'; // 导出变量
export const sqrt = Math.sqrt; //导出常量
export function myModule(someArg) { return someArg; } // 导出函数
import {myModule} from 'myModule';// 导入函数
import {name} from 'test';// 导入变量
3.箭头(Arrow)函数
这个特性使用频率非常高,对写代码带来了很大的便利,同时也要注意其中this的指向问题,箭头函数与包围它的代码共享同一个this
。
4.函数参数默认值
js
function foo(height = 50, color = 'red')
{
// ...
}
5.模板字符串
js
// 不使用模板字符串:
var name = 'Your name is ' + first + ' ' + last + '.'
// 使用模板字符串:
var name = `Your name is ${first} ${last}.`
6.解构赋值
方便从数组或者对象中快速提取值赋给定义的变量
js
var foo = ["one", "two", "three", "four"];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
//如果你要忽略某些值,你可以按照下面的写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"
//你也可以这样写
var a, b; //先声明变量
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
7.延展操作符(...)
js
const stuendts = ['Jine','Tom'];
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]
var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4);
console.log(arr2)//[1, 2, 3, 4]
// ES9中延展操作符增加了对对象的支持
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }
8.对象属性简写
js
const name='Ming',age='18',city='Shanghai';
const student = {
name:name,
age:age,
city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
// 使用对象属性简写特性
const name='Ming',age='18',city='Shanghai';
const student = {
name,
age,
city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
9.Promise
Promise 是异步编程的一种解决方案,比传统的解决方案callback更加的优雅。它最早由社区提出和实现的,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
10.支持let与const
区别 | var | let | const |
---|---|---|---|
是否有块级作用域 | × | ✔️ | ✔️ |
是否存在变量提升 | ✔️ | × | × |
是否添加全局属性 | ✔️ | × | × |
能否重复声明变量 | ✔️ | × | × |
是否存在暂时性死区 | × | ✔️ | ✔️ |
是否必须设置初始值 | × | × | ✔️ |
能否改变指针指向 | ✔️ | ✔️ | × |
11.Proxy
Proxy 可以理解成,在目标对象之前架设一层"拦截",外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Vue3就是基于Proxy
进行编写的。
12.for...of..循环
for...of
循环,作为遍历所有数据结构的统一的方法。
for...of
循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments
对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。
37、this的指向及其作用域
this的指向
常见的this指向:
- 全局作用域中或者普通函数中this指向全局对象window
- 立即执行函数this必定指向window
- 定时器this指向window
- 事件中this指向事件源对象
- 方法中谁调用就指向谁
- 构造函数中this指向对象实例
箭头函数本身并不具有this,箭头函数使用的是外层的this(即箭头函数处于那个作用域,就使用该作用域的this)
使用call、apply、bind可以显示修改this的指向。
举个例子:
js
const obj = {
myName: "大飞哥",
func: function(age, gender) {
console.log(`我的名字是${this.myName}, 我的年龄是${age},我是一个${gender}`);
}
}
const obj2 = {
myName: "小小飞"
}
obj.func.call(obj2, 18, "帅哥"); // 我的名字是小小飞, 我的年龄是18,我是一个帅哥
bind和call,apply最大的区别就是call,apply会立即执行方法,而bind并不会立即执行,而是会返回一个新方法供后面使用。
作用域
(1)全局作用域
- 直接写在script标签的JS代码,都在全局作用域。在全局作用域下声明的变量叫做全局变量(在块级外部定义的变量)。
- 全局变量在全局的任何位置下都可以使用;全局作用域中无法访问到局部作用域的中的变量。
- 全局作用域在页面打开的时候创建,在页面关闭时销毁。
- 所有 window 对象的属性拥有全局作用域
(2)函数作用域(局部作用域)
- 调用函数时会创建函数作用域,函数执行完毕以后,作用域销毁。每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的。
- 在函数作用域中可以访问全局变量,在函数的外面无法访问函数内的变量。
- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有就向上一作用域中寻找,直到找到全局作用域,如果全局作用域中仍然没有找到,则会报错。
(3)块级作用域
- ES6之前JavaScript采用的是函数作用域+词法作用域,ES6引入了块级作用域。
- 任何一对花括号{}中的语句集都属于一个块,在块中使用let和const声明的变量,外部是访问不到的,这种作用域的规则就叫块级作用域。
- 通过var声明的变量或者非严格模式下创建的函数声明没有块级作用域。
(4)词法作用域
- 词法作用域是静态的作用域,无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。
- 编译的词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的,从而能够预测在执行过中如何对它们进行查找。
- 换句话说,词法作用域就是你在写代码的时候就已经决定了变量的作用域。
38、 npm run dev执行过程
-
寻找
dev
脚本:npm
会在项目的package.json
文件中查找名为dev
的脚本字段。这个字段指定了在执行npm run dev
命令时要执行的具体脚本。 -
执行脚本:
npm
会根据找到的dev
脚本字段,执行指定的脚本。这个脚本可以是一个 JavaScript 文件、一个命令行指令,或者一个 shell 脚本。 -
安装依赖:如果你的
dev
脚本依赖其他的模块,npm
会在执行脚本之前自动安装这些依赖。这确保了在运行开发服务器时所需的所有模块都已经正确安装。 -
启动开发服务器:大多数情况下,
dev
脚本的主要目的是启动一个开发服务器。这个服务器可以是一个简单的 HTTP 服务器,用于提供静态文件,或者是一个复杂的 Web 应用程序服务器,如 Express 或 Webpack。 -
监听文件变化:开发服务器通常会监听项目中的文件变化,并在保存文件时自动重新加载服务器。这使得在开发过程中可以实时看到代码更改的效果,无需手动重新启动服务器。
39、 引用文件时经常用到的@符,一般指向的是哪,比如@component/xx.vue
在 Vue.js 中,@
符号通常用于指向项目中的资源路径。具体来说,它可以用于以下几种情况:
- 组件引用:当使用
@component
指令时,@
符号后面跟着的是组件的名称。例如,@component/xx.vue
表示引用名为xx.vue
的组件。 - 模板文件引用:在单文件组件中,可以使用
@
符号来引用其他模板文件。例如,@template
指令可以用来指定一个模板文件的路径。 - 样式文件引用:通过
@
符号,可以引用项目中的样式文件。例如,@/styles.css
表示引用根目录下的styles.css
文件。 - 图片等资源文件引用:类似地,使用
@
符号也可以引用图片、字体等资源文件。例如,@/image.png
表示引用根目录下的image.png
图片文件。
40、 事件代理(事件委托)
事件触发三阶段(JS事件流)
window
往事件触发处传播,遇到注册的捕获事件会触发- 传播到事件触发处时触发注册的事件
- 从事件触发处往
window
传播,遇到注册的冒泡事件会触发 - 总之:
事件捕获阶段
-->处于目标阶段
-->事件冒泡阶段
(先捕获事件再冒泡事件
)
事件冒泡、事件捕获
冒泡事件
:是指子元素向父元素传递的过程(从里到外)捕获事件
:是指父元素向子元素传递的过程(从外到里)
事件委托
事件委托的原理就是利用了浏览器事件冒泡的机制
由于事件冒泡过程中,会由子节点冒泡到父节点,并且可以在父节点的事件里获取到target
(实际触发的元素),这样子就可以在父节点上处理事件;
事件代理 的方式相较于直接给目标注册事件 来说,有以下优点
:
- 节省内存
- 不需要给子节点注销事件
- 事件代理时获取触发的子元素可以采用获取
target
来得知