面经知识点总结--js重要概念

  • ES6的新特性
  • 作用域
  • 为什么要新增块级作用域?
  • 块级作用域关键字: let const
  • promise



作为一名前端入门菜鸟,最近经历了春招实习面试的蹂躏,结合小一年的前端学习,项目开发的经历,尝试总结学习过程中遇到的问题,分享出来,与诸位学习前端的朋友互相交流,能力有限,有不足和错漏之处,希望能得到大家的指正和帮助!


千里之行,始于足下,学习之路漫漫,就此开始吧~

ES6的新特性

ES6: 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版。
目前ES标准每年发行一次,按照命名规则即:ES7(ES2016), ES8(ES2017)… 一些情况下ES6也泛指ES2015及之后的新增特性,虽然之后 的版本应当称为ES7、ES8等。
ES6新标准为解决ES中没有类等问题,添加了许多新特性。学习ES6很有必要,毕竟技术在不断更新嘛~当前前端主流的框架Vue、react等也是采用ES6的语法来实现的。

作用域

ES6相比较ES5,新增了块级作用域。ES5只有全局作用域(全局变量) 和 函数作用域

为什么要新增块级作用域?

ES5只有函数作用域会使用中造成的一些意料之外的问题:

1. 变量提升导致内层变量可能会覆盖外层变量
eg:

// 只有全局变量
var i = 5;
function func1() {
	console.log(i);
}
func1() // 5, 打印的是全局变量5

//有同名的内层函数变量,内层变量覆盖掉外层全局变量
var i = 5;
function func() {
	console.log(i);
	if (true) {
		var i = 6;
	}
}
func(); // undefined,

func()中,由于变量提升,定义的函数变量 i = 6, 覆盖掉了全局变量5,而打印是在局部变量定义前,因此结果为undefined

2.用来计数的循环变量泄露为全局变量

for (var i = 0; i < 10; i++) {  
    	console.log(i);  
}  
console.log(i);  // 10

块级作用域关键字: let const

ES6下新增了let和const关键字来声明变量,不同于var关键字,没有变量提升。但是要注意let 和const 具有暂存性死区特性

  1. let
    let 关键字用来声明一个在代码块(块级作用域, { }包裹的部分)生效的变量。与var的区别: var在作用域内可以重复声明,后者会覆盖前者的值;let在块级作用域里面不能重复声明。
// 不能重复声明let变量
function fn () {
   var foo = 'bar';
   var foo = 'newbar';   // 不报错
}
function fn () {
    let a =1;
    let a =2; // Uncaught SyntaxError: Identifier 'a' has already been declared
}
  1. const
    const 声明一个只读的常量,一旦声明,常量的值就不能改变。而且声明时,必须初始化。同样,也不能和所在作用域内的其他变量或函数拥有相同的名称。
const c = 1;
const c = 2; // Uncaught SyntaxError: Identifier 'c' has already been declared

几点注意:
const声明的只读常量也不是完全的不可修改,如,声明一个引用数据类型的常量,可以修改该常量的属性值:

// 创建常量数组
const cars = ["Saab", "Volvo", "BMW"];
// 修改元素
cars[0] = "Toyota";

promise

ES6一个贼重要的新特性: promise(诺言,7777哈哈,莫名想起莫厂子)。为了解决ES5回调函数使用中出现的回调地狱,大致就是回调函数里面层层嵌套回调,使得代码可读性变差,看起来复杂难以理解,ES6引入了一种新的异步回调方案就是promise。
简单的说,promise是一个对象,Promise 对象代表一个异步操作,有三种状态:
pending: 初始状态;
fulfilled: 意味着操作成功完成;
rejected: 意味着操作失败。
当我们创建一个promise对象时,方法如下:

var p = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、调用resolve 或 reject
    
    if (true) {
    resolve();
    } else {
    reject();
    }
});

Promise 构造函数接收一个函数作为参数,这个函数我们称为执行器函数,在执行器函数中执行一些操作(可以是异步请求),而这个执行器函数本身也传入两个回调函数作为参数(resolve和reject)。在执行器中执行操作(如异步请求等),如果一切都正常执行完成,则调用 resolve,否则调用 reject。resolve和reject回调函数是js封装好的。

说了这么多,promise怎么实现异步操作呢?
这里要提一下promise的then方法了, 当我们创建一个promise对象后,可以用then方法处理结果。then()接收两个函数,分别处理异步操作成功和失败两种情况。所以,当执行器中的异步操作完成后,调用了resolve(), 就会触发then方法中第一个函数,来处理异步操作成功后的结果; 如果异步操作失败,调用reject(), 就出发第二个函数来处理异步异常。

var p = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、调用resolve 或 reject
    if (requst()) {
    resolve('我是response数据');
    } else {
    reject('我是error');
    }
});
p.then((res) => {
	console.log(res);  // '我是response数据'
},
(err) => {
	console.log(err); // '我是error'
})

resolve和reject回调函数是可以接收数据的(异步请求的res或者err),在then方法里面可以获取这个数据,从而处理异步操作的结果。