黑马程序员前端JavaScript高级——ES6学习笔记

简单看下开头目录,里面包含了面向对象的编程思想,以及构造函数,类和对象、原型链、箭头函数、数组和字符串新增方法、函数递归、深拷贝浅拷贝、正则表达式等知识点。本文是对CSDN其他博主记录的一个补充,因为黑马也是今年才陆续补充一些知识点的视频的,本文将其收录于此,雷同勿怪。

目录

Day 1 - JavaScript 面向对象

01 - 学习目标(target)

02 - 面向对象编程介绍

面向过程编程 POP(Process- oriented programming)

面向对象编程 OOP(Object Oriented Programming)

03 - ES6 中的类和对象

对象

类 class

创建类和对象:

类添加方法:

04 - 类的继承

super 关键字

使用类注意事项

Day 2 - 构造函数和原型

01 - 学习目标(target)

02 - 构造函数和原型

概述

构造函数

构造函数原型 prototype 

对象原型 __proto__ 

constructor 构造函数

构造函数、实例、原型对象三者之间的关系

原型链

JavaScript 的成员查找机制(规则)

原型对象this指向

扩展内置对象

03 - 继承

call()方法

借用构造函数继承父类型属性

借用原型对象继承父类型方法

ES6 类的本质

04 - ES5 中的新增方法

概述

数组方法

字符串方法

对象方法

Day 3 - 函数进阶

01 - 学习目标(target) 

02 - 函数的定义和调用

函数的定义方式  

函数的调用方式

03 - this 的指向 

改变函数内部 this 指向

call apply bind 总结

04 - 严格模式 

什么是严格模式

开启严格模式

严格模式中的变化

05 - 高阶函数

06 - 闭包

变量作用域

什么是闭包

在 chrome 中调试闭包 

闭包的作用

闭包应用 --- 点击 li 输出索引号

闭包案例

闭包总结

07 - 递归

什么是递归

利用递归求数学题

浅拷贝和深拷贝

Day 4 - 正则表达式

01 - 学习目标(target)

02 - 正则表达式概述

什么是正则表达式

正则表达式的特点

03 - 正则表达式在 JavaScript 中的使用

创建正则表达式

测试正则表达式 test

04 - 正则表达式中的特殊字符

正则表达式的组成 

边界符

字符类

量词符

案例:用户名验证

括号总结

预定义类

案例:座机号验证

05 - 正则表达式中的替换

replace 替换

正则表达式参数

案例:敏感词过滤

Day 5 - ES6部分知识 

01 - 学习目标(target )

02 - ES6简介

什么是ES6

为什么使用ES6

03 - ES6 的新增语法

let 关键字

经典面试题

const 关键字

let、const、var 的区别

解构赋值

箭头函数

剩余参数

04 - ES6 的内置对象扩展

Array 的扩展方法 

String 的扩展方法

Set 数据结构


Day 1 - JavaScript 面向对象

01 - 学习目标(target)

  • 能够说出什么是面向对象
  • 能够说出类和对象的关系
  • 能够使用 class 创建自定义类型
  • 能够说出什么是继承

02 - 面向对象编程介绍

面向过程编程 POP(Process- oriented programming)

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依 次调用就可以了。

面向过程,就是按照我们分析好了的步骤,按照步骤解决问题。

面向对象编程 OOP(Object Oriented Programming)

面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。

举个例子:将大象装进冰箱,面向对象做法。

先找出对象,并写出这些对象的功能:

1. 大象对象

● 进去

2. 冰箱对象

● 打开

● 关闭

3. 使用大象和冰箱的功能

面向对象是以对象功能来划分问题,而不是步骤。

面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。

其特性:

  • 封装性
  • 继承性
  • 多态性

面向过程和面向对象的对比

面向过程 面向对象
优点 性能比面向对象高,适合跟硬件联系很紧密 的东西,例如单片机就采用的面向过程编程。 易维护、易复用、易扩展,由于面向对象有 封装、继承、多态性的特性,可以设计出低耦合的 系统,使系统 更加灵活、更加易于维护
缺点 没有面向对象易维护、易复用、易扩展 性能比面向过程低

03 - ES6 中的类和对象

对象

 对象是一个具体的事物在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、 函数等。

 对象是由属性方法组成的:

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)

类 class

在 ES6 中新增的类概念,可以用关键字 class 声明一个类,之后以这个类来实例化对象。

抽象了对象的公共部分,它泛指某一大类(class)。

对象特指某一个,通过类实例化一个具体的对象。

面向对象的思维特点:

1. 抽取(抽象)对象共用的属性和行为组织(封装)成一个(模板)

2. 对类进行实例化, 获取类的对象

创建类和对象:

注意:类必须使用 new 实例化对象;

constructor() 方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过 new 命令生成对象实例时,自动调用该方法。如果没有显示定义,,类内部会自动给我们创建一个constructor()

类添加方法:

04 - 类的继承

程序中的继承:子类可以继承父类的一些属性和方法。

语法:

黑马程序员前端JavaScript高级——ES6学习笔记_第1张图片

super 关键字

super 关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数。

语法:

黑马程序员前端JavaScript高级——ES6学习笔记_第2张图片

黑马程序员前端JavaScript高级——ES6学习笔记_第3张图片

注意:子类在构造函数中使用 super, 必须放到 this 前面 (必须先调用父类的构造方法,在使用子类构造方法)

类的继承实例: 

 

super 关键字调用父类普通函数 实例 

 子类继承父类同时继承扩展自己的方法:

使用类注意事项

三个注意点:

  1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象。
  2. 类里面的共有属性和方法一定要加this使用。
  3. 类里面的this指向问题。
  4. constructor 里面的this指向实例对象, 方法里面的this 指向这个方法的调用者。




    
    
    
    Document



    
    


Day 2 - 构造函数和原型

01 - 学习目标(target)

  •  能够使用构造函数创建对象
  • 能够说出原型的作用
  • 能够说出访问对象成员的规则
  • 能够使用 ES5新增的一些方法

02 - 构造函数和原型

概述

在 ES6 之前,JS 中并没有引入类的概念。ES6, 全称 ECMAScript 6.0 ,2015.06 发版。但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏 览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。

在 ES6之前 ,对象不是基于类创建的,而是用一种称为构建函数的特殊函数来定义对象和它们的特征。

创建对象可以通过三种方式:(ES6之前的方法)

  • 对象字面量
  • new   Object()
  • 自定义构造函数

构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new一起使用。我 们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

在 JS 中,使用构造函数时要注意以下两点:

  • 构造函数用于创建某一类对象,其首字母要大写
  • 构造函数要和 new 一起使用才有意义

new 在执行时会做四件事情:

① 在内存中创建一个新的空对象。

② 让 this 指向这个新的对象。

③ 执行构造函数里面的代码,给这个新对象添加属性和方法。

④ 返回这个新对象(所以构造函数里面不需要 return )。

JavaScript 的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数内部的 this 上添 加。通过这两种方式添加的成员,就分别称为静态成员实例成员

  • 静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身来访问
  • 实例成员:在构造函数内部创建的对象成员称为实例成员,只能由实例化的对象来访问

构造函数方法虽然很好用,但是存在浪费内存的问题

比如:

function Star(uname, age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log('我会唱歌');
}
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
console.log(ldh.sing === zxy.sing)  // false

黑马程序员前端JavaScript高级——ES6学习笔记_第4张图片

 我们希望所有的对象使用同一个函数,这样就比较节省内存,那么我们要怎样做呢?

构造函数原型 prototype 

构造函数通过原型分配的函数是所有对象所共享的。 

JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。注意这个 prototype 就是一 个对象,这个对象的所有属性和方法,都会被构造函数所拥有 

我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。 

因此,上述例子可进行如下修改 :

 因此,原型是什么?

答:一个对象,我们也称为 prototype原型对象

原型的作用是什么?

答:共享方法

对象原型 __proto__ 

对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。

  • __proto__对象原型和原型对象 prototype 是等价的 ;
  • __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性, 因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype。
 

黑马程序员前端JavaScript高级——ES6学习笔记_第5张图片

constructor 构造函数

对象原型( __proto__)构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。 

constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋 值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。 此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

构造函数、实例、原型对象三者之间的关系

黑马程序员前端JavaScript高级——ES6学习笔记_第6张图片

原型链

 

黑马程序员前端JavaScript高级——ES6学习笔记_第7张图片

JavaScript 的成员查找机制(规则)

① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。

② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。

③ 如果还没有就查找原型对象的原型(Object的原型对象)。

④ 依此类推一直找到 Object 为止(null)。

⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。

原型对象this指向

构造函数中的 this 指向我们实例对象。

原型对象里面放的是方法,这个方法里面的 this 指向的是这个方法的调用者, 也就是这个实例对象。 

 

扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法。比如给数组增加自定义求偶数和的功能。

注意:数组和字符串内置对象不能给原型对象覆盖操作 Array.prototype = {} ,只能是 Array.prototype.xxx = function(){} 的方式。 

03 - 继承

ES6之前并没有给我们提供 extends 继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承。

call()方法

调用这个函数, 并且修改函数运行时的 this 指向

  • thisArg :当前调用函数 this 的指向对象
  • arg1,arg2:传递的其他参数

借用构造函数继承父类型属性

核心原理: 通过 call() 把父类型的 this 指向子类型的 this ,这样就可以实现子类型继承父类型的属性。

黑马程序员前端JavaScript高级——ES6学习笔记_第8张图片

借用原型对象继承父类型方法

一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类方法。 

核心原理:

① 将子类所共享的方法提取出来,让子类的 prototype 原型对象 = new 父类() 

② 本质:子类原型对象等于是实例化父类,因为父类实例化之后另外开辟空间,就不会影响原来父类原型对象

③ 将子类的 constructor 从新指向子类的构造函数

ES6 类的本质

  1.  class 本质还是 function。
  2. 类的所有方法都定义在类的 prototype 属性上
  3. 类创建的实例,里面也有 __proto__ 指向类的 prototype 原型对象
  4. 所以 ES6 的类它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
  5. .所以ES6的类其实就是语法糖
  6. 语法糖:语法糖就是一种便捷写法。 简单理解,有两种方法可以实现同样的功能,但是一种写法更加清晰、方便,那么这个方法就是语法糖

04 - ES5 中的新增方法

概述

ES5 中给我们新增了一些方法,可以很方便的操作数组或者字符串,这些方法主要包括:

  • 数组方法
  • 字符串方法
  • 对象方法

数组方法

迭代(遍历)方法:forEach()、map()、filter()、some()、every();

forEach()方法

  •  currentValue:数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象本身

filter()方法

  • filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组 
  • 注意它直接返回一个新数组
  • currentValue: 数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象本身

some()方法

 

  •  some() 方法用于检测数组中的元素是否满足指定条件. 通俗点 查找数组中是否有满足条件的元素
  • 注意它返回值是布尔值, 如果查找到这个元素, 就返回true , 如果查找不到就返回false。
  • 如果找到第一个满足条件的元素,则终止循环. 不在继续查找。
  • currentValue: 数组当前项的值
  • index:数组当前项的索引
  • arr:数组对象本身

 forEach()和some的区别

字符串方法

trim() 方法会从一个字符串的两端删除空白字符。

trim() 方法并不影响原字符串本身,它返回的是一个新的字符串。





    
    
    
    Document



     
    

对象方法

1. Object.keys() 用于获取对象自身所有的属性

  • 效果类似 for…in 
  • 返回一个由属性名组成的数组

2. Object.defineProperty() 定义对象中新属性或修改原有的属性。(了解)

  • obj:必需。目标对象 
  • prop:必需。需定义或修改的属性的名字
  • descriptor:必需。目标属性所拥有的特性

Object.defineProperty() 第三个参数 descriptor 说明: 以对象形式 { } 书写

  • value: 设置属性的值 默认为undefined
  • writable: 值是否可以重写。true | false 默认为false
  • enumerable: 目标属性是否可以被枚举。true | false 默认为 false
  • configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false 默认为false

Day 3 - 函数进阶

01 - 学习目标(target) 

  • 能够说出函数的多种定义和调用方式 
  • 能够说出和改变函数内部 this 的指向
  • 能够说出严格模式的特点
  • 能够把函数作为参数和返回值传递
  • 能够说出闭包的作用
  • 能够说出递归的两个条件
  • 能够说出深拷贝和浅拷贝的区别

02 - 函数的定义和调用

函数的定义方式  

1. 函数声明方式 function 关键字 (命名函数)

2. 函数表达式 (匿名函数)

3. new Function()

  • Function 里面参数都必须是字符串格式 
  • 第三种方式执行效率低,也不方便书写,因此较少使用
  • 所有函数都是 Function 的实例(对象)
  • 函数也属于对象

黑马程序员前端JavaScript高级——ES6学习笔记_第9张图片

函数的调用方式

03 - this 的指向 

原则

this 的指向是在我们调用函数的时候确定的。调用方式的不同决定了 this 的指向不同。一般指向的是我们的调用者。





    
    
    
    Document



    
    


改变函数内部 this 指向

JavaScript 为我们专门提供了一些函数方法来帮我们更优雅的处理函数内部 this 的指向问题,常用的有 call()、apply()、bind()三种方法。

1. call 方法 

call() 方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。 

语法结构为:

fun.call(thisArg, arg1, arg2, ...) 
  •  thisArg:在 fun 函数运行时指定的 this 值;
  • arg1,arg2:传递的其他参数;
  • 返回值就是函数的返回值,因为它就是调用函;
  • 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承。

 2. apply 方法

apply() 方法调用一个函数。简单理解为调用函数的方式,它也可以改变函数的 this 指向。

语法结构为:

fun.apply(thisArg, [argsArray])
  • thisArg:在 fun 函数运行时指定的 this 值;
  • argsArray:传递的值,必须包含在数组里面;
  • 返回值就是函数的返回值,因为它就是调用函数;
  • 因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值。

 3. bind 方法

bind() 方法不会调用函数。但是能改变函数内部 this 指向。

语法结构为:

fun.bind(thisArg, arg1, arg2, ...)
  • thisArg:在 fun 函数运行时指定的 this 值;
  • arg1,arg2:传递的其他参数;
  • 返回由指定的 this 值和初始化参数改造的原函数拷贝;
  • 因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind。




    
    
    
    Document



    
    
    
    


call apply bind 总结

相同点:

 都可以改变函数内部的 this 指向。

区别点:

1. call 和 apply 会调用函数, 并且改变函数内部 this 指向;

2. call 和 apply 传递的参数不一样, call 传递参数 aru1, aru2..形式 apply 必须数组形式[arg];

3. bind 不会调用函数, 可以改变函数内部this指向。

主要应用场景:

1. call 经常做继承;

2. apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值;

3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的 this 指向。

04 - 严格模式 

什么是严格模式

JavaScript 除了提供正常模式外,还提供了严格模式(strict mode)。ES5 的严格模式是采用具有限制性 JavaScript 变体的一种方式,即在严格的条件下运行 JS 代码。

严格模式在 IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。

严格模式对正常的 JavaScript 语义做了一些更改:

1. 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。

2. 消除代码运行的一些不安全之处,保证代码运行的安全。

3. 提高编译器效率,增加运行速度。

4. 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比 如一些保留字如:class, enum, export, extends, import, super 不能做变量名

开启严格模式

严格模式可以应用到整个脚本个别函数中。因此在使用时,我们可以将严格模式分为为脚本开启严格模式为函数开启严格模式两种情况。

1. 为脚本开启严格模式

有的 script 基本是严格模式,有的 script 脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件 放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他 script 脚本文件。 


 2. 为函数开启严格模式

要给某个函数开启严格模式,需要把“use strict”; (或 'use strict'; ) 声明放在函数体所有语句之前

function fn(){
    "use strict";
    return "这是严格模式。";
}

 将 "use strict" 放在函数体的第一行,则整个函数以 "严格模式" 运行。


    
    
    
    
    

严格模式中的变化

严格模式对 Javascript 的语法和行为,都做了一些改变。

1. 变量规定

① 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量都必须先用 var 命令声明,然后再使用。

② 严禁删除已经声明变量。例如,delete x; 语法是错误的。 

2. 严格模式下 this 指向问题

① 以前在全局作用域函数中的 this 指向 window 对象。

② 严格模式下全局作用域中函数中的 this 是 undefined。

③ 以前构造函数时不加 new也可以 调用,当普通函数,this 指向全局对象

④ 严格模式下,如果 构造函数不加new调用, this 指向的是undefined 如果给他赋值则 会报错

⑤ new 实例化的构造函数指向创建的对象实例。

⑥ 定时器 this 还是指向 window 。

⑦ 事件、对象还是指向调用者。

3. 函数变化

① 函数不能有重名的参数

② 函数必须声明在顶层。新版本的 JavaScript 会引入“块级作用域”( ES6 中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。

更多严格模式要求参考:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

05 - 高阶函数

高阶函数是对其他函数进行操作的函数,它接收函数作为参数将函数作为返回值输出



此时 fn 就是一个高阶函数

函数也是一种数据类型,同样可以作为参数,传递给另外一个参数使用。 最典型的就是作为回调函数。

同理函数也可以作为返回值传递回来





    
    
    
    Document
    
    



    

06 - 闭包

变量作用域

变量根据作用域的不同分为两种:全局变量和局部变量。

1. 函数内部可以使用全局变量。

2. 函数外部不可以使用局部变量。

3. 当函数执行完毕,本作用域内的局部变量会销毁。

什么是闭包

闭包(closure)指有权访问另一个函数作用域中变量函数。 ----- JavaScript 高级程序设计

简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。 

在 chrome 中调试闭包 

1. 打开浏览器,按 F12 键启动 chrome 调试工具。

2. 设置断点。

3. 找到 Scope 选项(Scope 作用域的意思)。

4. 当我们重新刷新页面,会进入断点调试,Scope 里面会有两个参数(global 全局作用域、local 局部作用域)。

5. 当执行到 fn2() 时,Scope 里面会多一个 Closure 参数 ,这就表明产生了闭包。

闭包的作用

闭包应用 --- 点击 li 输出索引号





    
    
    
    Document



    
    


闭包案例

1. 循环注册点击事件。

2. 循环中的 setTimeout()。

3. 计算打车价格。

思考题:

闭包总结

1. 闭包是什么?

闭包是一个函数 (一个作用域可以访问另外一个函数的局部变量)

2. 闭包的作用是什么?

延伸变量的作用范围

07 - 递归

什么是递归

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

简单理解:函数内部自己调用自己,这个函数就是递归函数。

递归函数的作用和循环效果一样

由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return

利用递归求数学题

1. 求 1 * 2 *3 ... * n 阶乘。

2. 求斐波那契数列 。 

3. 根据id返回对应的数据对象

浅拷贝和深拷贝

1. 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。

2. 深拷贝拷贝多层,每一级别的数据都会拷贝。

3. Object.assign(target, ...sources) es6 新增方法可以浅拷贝

浅拷贝:

深拷贝:

Day 4 - 正则表达式

01 - 学习目标(target)

  • 能够说出正则表达式的作用 
  • 能够写出简单的正则表达式
  • 能够使用正则表达式对表单进行验证
  • 能够使用正则表达式替换内容

02 - 正则表达式概述

什么是正则表达式

正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也 是对象。

正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字 母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一 些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。

其他语言也会使用正则表达式,本阶段我们主要是利用 JavaScript 正则表达式完成表单验证。 

正则表达式的特点

1. 灵活性、逻辑性和功能性非常的强。

2. 可以迅速地用极简单的方式达到字符串的复杂控制。

3. 对于刚接触的人来说,比较晦涩难懂。比如: ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

4. 实际开发,一般都是直接复制写好的正则表达式. 但是要求会使用正则表达式并且根据实际情况修改正则表达 式. 比如用户名: /^[a-z0-9_-]{3,16}$/ 

03 - 正则表达式在 JavaScript 中的使用

创建正则表达式

在 JavaScript 中,可以通过两种方式创建一个正则表达式。

1. 通过调用 RegExp 对象的构造函数创建

      var 变量名 = new RegExp(/表达式/);

2. 通过字面量创建

      var 变量名 = /表达式/ ;

// 注释中间放表达式就是正则字面量

测试正则表达式 test

test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符串。

 regexObj.test(str)
  • regexObj 是写的正则表达式
  • str 我们要测试的文本
  • 就是检测str文本是否符合我们写的正则表达式规范。

04 - 正则表达式中的特殊字符

正则表达式的组成 

一个正则表达式可以由简单的字符构成,比如 /abc/,也可以是简单和特殊字符的组合,比如 /ab*c/ 。其中 特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如 ^ 、$ 、+ 等。 

特殊字符非常多,可以参考:

● MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

● jQuery 手册:正则表达式部分

● 正则测试工具:http://tool.oschina.net/regex

这里我们把元字符划分几类学习 。

边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符。 

边界符 说明
^ 表示匹配行首的文本(以谁开始)
$ 表示匹配行尾的文本(以谁结束)

如果 ^ 和 $ 在一起,表示必须是精确匹配。

 

字符类

字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。 

1. [] 方括号

/[abc]/.test('andy') // true 

 后面的字符串只要包含 abc 中任意一个字符,都返回 true 。

2. [-] 方括号内部范围符-

/^[a-z]$/.test(c') // true

方括号内部加上 - 表示范围,这里表示 a 到 z 26个英文字母都可以。

3. [^] 方括号内部 取反符^

/[^abc]/.test('andy') // false

方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。

注意和边界符 ^ 区别,边界符写到方括号外面。

4. 字符组合

/[a-z1-9]/.test('andy') // true

 方括号内部可以使用字符组合,这里表示包含 a 到 z 的26个英文字母和 1 到 9 的数字都可以。

量词符

量词符用来设定某个模式出现的次数。 

量词         说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

案例:用户名验证

功能需求:

1. 如果用户名输入合法, 则后面提示信息为 : 用户名合法,并且颜色为绿色

2. 如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为绿色

分析:

1. 用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为 6~16位

2. 首先准备好这种正则表达式模式 /$[a-zA-Z0-9-_]{6,16}^/

3. 当表单失去焦点就开始验证

4. 如果符合正则规范, 则让后面的span标签添加 right 类

5. 如果不符合正则规范, 则让后面的span标签添加 wrong 类





    
    
    
    Document
    



     请输入用户名
    


括号总结

1. 大括号  量词符。里面表示重复次数

2. 中括号  字符集合。匹配方括号中的任意字符。

3. 小括号  表示优先级

可以在线测试:https://c.runoob.com/

预定义类

预定义类指的是某些常见模式的简写方式。 

预定类 说明
\d 匹配0-9之间的任一数字。相当于[0-9]
\D 匹配0-9以外的字符。相当于[^0-9]
\w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
\W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
\s 匹配空格(包括换行符、制表符、空格符等),相当于[\t\r\n\v\f]
\S 匹配非空格字符,相当于[^\t\r\n\v\f]

案例:座机号验证

05 - 正则表达式中的替换

replace 替换

replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。 

stringObject.replace(regexp/substr,replacement)
  •  第一个参数:被替换的字符串 或者 正则表达式
  • 第二个参数:替换为的字符串
  • 返回值是一个替换完毕的新字符串

正则表达式参数

/表达式/[switch]

 switch(也称为修饰符) 按照什么样的模式来匹配. 有三种值:

● g:全局匹配

● i:忽略大小写

● gi:全局匹配 + 忽略大小写

案例:敏感词过滤





    
    
    
    Document
    



     
    

Day 5 - ES6部分知识 

01 - 学习目标(target )

  • 能够说出使用let关键字声明变量的特点
  • 能够使用解构赋值从数组中提取值
  • 能够说出箭头函数拥有的特性
  • 能够使用剩余参数接收剩余的函数参数
  • 能够使用拓展运算符拆分数组
  • 能够说出模板字符串拥有的特性

02 - ES6简介

什么是ES6

ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。 

黑马程序员前端JavaScript高级——ES6学习笔记_第10张图片 ES6 实际上是一个泛指,泛指 ES2015 及后续的版本。

为什么使用ES6

每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。

  • 变量提升特性增加了程序运行时的不可预测性
  • 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码

03 - ES6 的新增语法

let 关键字

ES6中新增的用于声明变量的关键字。

● let声明的变量只在所处于的块级有效

if (true) {
    let a = 10;
}
console.log(a) // a is not defined

 注意:使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。

● 不存在变量提升 

console.log(a); // a is not defined 
let a = 20;

● 暂时性死区

var tmp = 123;
  if (true) {
    tmp = 'abc';
    let tmp;
}

经典面试题

黑马程序员前端JavaScript高级——ES6学习笔记_第11张图片经典面试题图解:此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的值。

 黑马程序员前端JavaScript高级——ES6学习笔记_第12张图片

经典面试题图解:此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值。

const 关键字

作用:声明常量,常量就是值(内存地址)不能变化的量。

● 具有块级作用域 

if (true) {
  const a = 10;
}
console.log(a) // a is not defined

● 声明常量时必须赋值

const PI; // Missing initializer in const declaration

● 常量赋值后,值不能修改。

const PI = 3.14;
PI = 100; // Assignment to constant variable. 
const ary = [100, 200];
ary[0] = 'a';
ary[1] = 'b';
console.log(ary); // ['a', 'b']; 
ary = ['a', 'b']; // Assignment to constant variable.

let、const、var 的区别

1. 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。

2. 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。

3. 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值。 

黑马程序员前端JavaScript高级——ES6学习笔记_第13张图片

解构赋值

ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也可以实现解构。

数组解构 

let [a, b, c] = [1, 2, 3];
console.log(a)
console.log(b)
console.log(c)

如果解构不成功,变量的值为undefined。

let [foo] = [];
let [bar, foo] = [1];

对象解构

let person = { name: 'zhangsan', age: 20 };
let { name, age } = person;
console.log(name); // 'zhangsan' 
console.log(age); // 20
let {name: myName, age: myAge} = person; // myName myAge 属于别名
console.log(myName); // 'zhangsan' 
console.log(myAge); // 20

箭头函数

ES6中新增的定义函数的方式。

() => {} 
const fn = () => {}

 函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号

function sum(num1, num2) {
    return num1 + num2;
}
const sum = (num1, num2) => num1 + num2;

如果形参只有一个,可以省略小括号

function fn (v) {
    return v;
}
const fn = v => v;

箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this

const obj = { name: '张三'}
function fn () {
    console.log(this);
    return () => {
      console.log(this)
    }
}
const resFn = fn.call(obj);
resFn();

箭头函数面试题        

剩余参数

剩余参数语法允许我们将一个不定数量的参数表示为一个数组。

function sum (first, ...args) {
    console.log(first); // 10
    console.log(args); // [20, 30] 
}
sum(10, 20, 30)

 剩余参数和解构配合使用

let students = ['wangwu', 'zhangsan', 'lisi'];
let [s1, ...s2] = students;
console.log(s1); // 'wangwu' 
console.log(s2); // ['zhangsan', 'lisi']

04 - ES6 的内置对象扩展

Array 的扩展方法 

扩展运算符(展开语法) 

扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。

let ary = [1, 2, 3];
...ary // 1, 2, 3
console.log(...ary); // 1 2 3
console.log(1, 2, 3)

扩展运算符可以应用于合并数组。

// 方法一
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [...ary1, ...ary2];
// 方法二
ary1.push(...ary2);

将类数组或可遍历对象转换为真正的数组

let oDivs = document.getElementsByTagName('div');
oDivs = [...oDivs];



	
	扩展运算符


	
1
4
3
6
2
5

构造函数方法:Array.from()

将类数组或可遍历对象转换为真正的数组

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

let arrayLike = {
    "0": 1,
    "1": 2,
    "length": 2
}
let newAry = Array.from(aryLike, item => item *2)

实例方法:find()

用于找出第一个符合条件的数组成员,如果没有找到返回undefined

let ary = [{
    id: 1,
    name: '张三‘
}, {
    id: 2,
    name: '李四‘
}];
let target = ary.find((item, index) => item.id == 2)

实例方法:findIndex() 

 用于找出第一个符合条件的数组成员的位置,如果没有找到返回 -1

let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2

实例方法:includes()

表示某个数组是否包含给定的值,返回布尔值。

[1, 2, 3].includes(2) // true 
[1, 2, 3].includes(4) // false

String 的扩展方法

模板字符串 

ES6新增的创建字符串的方式,使用反引号定义。

let name = `zhangsan`;

 模板字符串中可以解析变量。

let name = '张三';
let sayHello = `hello,my name is ${name}`; // hello, my name is zhangsan

模板字符串中可以换行

let result = {
    name: 'zhangsan',
    age: 20,
    sex: '男'
}
let html = ` 
${result.name} ${result.age} ${result.sex}
`;

在模板字符串中可以调用函数

const sayHello = function () {
    return '哈哈哈哈 追不到我吧 我就是这么强大';
};
let greet = `${sayHello()} 哈哈哈哈`;
console.log(greet); // 哈哈哈哈 追不到我吧 我就是这么强大 哈哈哈哈

实例方法:startsWith() 和 endsWith()

● startsWith():表示参数字符串是否在原字符串的头部,返回布尔值

● endsWith():表示参数字符串是否在原字符串的尾部,返回布尔 

let str = 'Hello world!';
str.startsWith('Hello') // true 
str.endsWith('!') // true

实例方法:repeat()

repeat方法表示将原字符串重复n次,返回一个新字符串。

'x'.repeat(3) // "xxx" 
'hello'.repeat(2) // "hellohello"

Set 数据结构

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();

 Set函数可以接受一个数组作为参数,用来初始化。

const set = new Set([1, 2, 3, 4, 4]);

实例方法

● add(value):添加某个值,返回 Set 结构本身

● delete(value):删除某个值,返回一个布尔值,表示删除是否成功

● has(value):返回一个布尔值,表示该值是否为 Set 的成员

● clear():清除所有成员,没有返回值 

const s = new Set();
s.add(1).add(2).add(3); // 向 set 结构中添加值
s.delete(2) // 删除 set 结构中的2值
s.has(1) // 表示 set 结构中是否有1这个值 返回布尔值
s.clear() // 清除 set 结构中的所有值

遍历

Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。

s.forEach(value => console.log(value))

到这儿就结束了,本文主要包含黑马前端教程关于ES6部分的PPT和实例代码,希望对大家有所帮助,若文中有错误,欢迎在评论区下方指出,谢谢!

你可能感兴趣的:(JavaScript,学习笔记和案例,es6,学习,前端)