学然后知不足,教然后知困。知不足,然后能自反也;知困,然后能自强也

0%

ES6知识点笔记(1)

本文记录一下常见的ES6知识点。参考:http://caibaojian.com/es6/class.html

1、javascript的作用域

  • ES5中的var是没有块级作用域的(例如在 if/for 中)

  • ES6中的let是有块级作用的(例如在 if/for 中)

  • ES5之前因为if和for都没有块级作用域的概念, 所以在很多时候, 我们都必须借助于function的作用域来解决应用外面变量的问题

  • ES6中,加入了 let, let 它是有if 和 for 的块级作用域

image-20201223110754587

1.1 var 的局限性

先看一个ES5中经典的小案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>

<script>
// 1.没有块级作用域引起的问题: for的块级
var btns = document.getElementsByTagName('button');
for (var i=0; i<btns.length; i++) {
btns[i].addEventListener('click', function () {
console.log('第' + i + '个按钮被点击');
})
}
</script>
</body>

image-20201223112159023

无论点击那个按钮,都是打印“第3个按钮被点击”。这是因为for代码块没有作用域,当for循环绑定监听完成的时候,i是几?是3

ES5如何避免这个问题呢?可以使用闭包来解决:为什么闭包可以解决问题: 因为函数是一个作用域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>

<script>

// 2.情况二: ES5中使用闭包,为什么闭包可以解决问题: 函数是一个作用域.
var btns = document.getElementsByTagName('button');
for (var i=0; i<btns.length; i++) {
(function (i) {
btns[i].addEventListener('click', function () {
console.log('第' + i + '个按钮被点击');
})
}) (i)
}
</script>

image-20201223112128906

1.2 let 的使用方式

事实上var的设计可以看成JavaScript语言设计上的错误。但是这种错误多半不能修复和移除, 以为需要向后兼容。ES6添加了一个新的关键字: let。我们可以将let看成更完美的var。

同样是上面的问题,如果使用let则非常简单:

image-20201223112956559

image-20201223112928447

2 、const的使用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
// 1.注意一: 一旦给const修饰的标识符被赋值之后, 不能修改
const name = 'why';
name = 'abc';//报错 Uncaught TypeError: Assignment to constant variable.

// 2.注意二: 在使用const定义标识符,必须进行赋值
const name;//报错 Uncaught SyntaxError: Missing initializer in const declaration

// 3.注意三: 常量的含义是指向的对象不能修改, 但是可以改变对象内部的属性.
const obj = {
name: 'why',
age: 18,
height: 1.88
}
// obj = {} //报错 Uncaught TypeError: Assignment to constant variable.
console.log(obj);

obj.name = 'kobe';
obj.age = 40;
obj.height = 1.87;

console.log(obj);
</script>

3、对象字面量的增强写法

针对对象字面量进行了很多增强。

ES5中定义对象代码如下:

image-20201223115628866

ES6中定义对象,代码如下:

image-20201223115726421

4、箭头函数

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

下面代码是普通函数定义与箭头函数的对比:

image-20201228170924828

箭头函数的写法更为简便,箭头左侧定义参数,箭头右侧定义函数体。当函数体为一行内容时,return关键字可以省略。

5、this指针

5.1 对象中的this指针

在对象中,this指针指向的就是对象本身。this可以引用对象的属性和方法。

image-20201228182127134

5.2 全局环境中的this指针

全局环境中,this指针指向window全局对象。

image-20201228182155315

5.3 函数中的this指针

谁调用函数,函数内的this指针就指向谁,我们平时在使用js函数时,在全局环境下实际是window对象调用函数。

image-20201228182239926

在函数的内部this指针的指向有两种可能:

  • 在严格模式下,this指针为undefined。严格模式,是js更严谨、更安全的一种发展方向的体现。
  • 在非严格模式下,this指向window全局对象

5.4 this指针使用过程中存在的一个问题

image-20201228182415008

我们期望的执行结果是“james—35”,但是实际的执行结果是“undefined—undefined”。
谁调用函数,函数内的this指针就指向谁。那么哪个对象调用了setTimeout的定时函数呢?
是player1么?不是,是window。window没有nickname和age属性,所以打印“undefined—undefined”。

那么我们怎么解决这个问题呢?,下面三种方法都可以打印我们期望的结果:“james—35”

  • 额外定义this指针的替身

    image-20201228182529781

  • 使用bind(this)

    image-20201228182553182

  • 箭头函数

    image-20201228182617949

6、高阶函数

高阶函数不在ES6的范畴中,但是这里把常见的高阶函数记录一下。

Higher-order function。JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。