ES6中的类和对象
类constructor构造函数
constructor
方法是类的构造函数(默认方法),用于传递参数,返回实例对象。
通过new
命令生成对象实例时,自动调用该方法。如果没有显式定义,类内部会自动创建一个constructor(){}
class Star{ constructor(uname){ this.uname= uname; } }
var ldh = new Star("刘德华");
注意:类必须使用new实例化对象
类内添加共有方法
多个函数之间不需要用,
分隔,函数前面不用写function
类继承extends
和super
关键字
class Son extends Father {}
super
关键字用于访问和调用对象父类上的函数(构造或普通函数都可以)
super()必须在子类构造函数内this前面调用
在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象。
构造函数和原型
在ES6之前,对象不是基于类创建的,而是用一种称为构造函数
的特殊函数来定义对象和它们的特征。
- 实例成员:构造函数内部通过this添加的成员,只能通过实例化的对象来访问
- 静态成员:在构造函数本身上添加的成员,
Star.sex= '男'
,只能通过构造函数访问
构造函数原型对象prototype
Star.prototype.sing= function(){}
这样sing
就能实现方法共享
对象原型__proto__
对象
都会有一个属性__proto__
指向构造函数的prototype原型对象
ldh.__proto__ === Star.prototype
__proto__
对象原型的意义就在于为对象的查找机制提供一个方向或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype
- 方法的查找规则:首先看ldh对象身上是否有
sing
方法,如果有就执行ldh对象上的sing
- 如果ldh对象上没有
sing
方法,因为ldh身上有__proto__
属性,就可以去构造函数原型对象prototype身上去查找sing这个方法
constructor
属性
对象原型__proto__
和构造函数原型对象prototype
里面都有一个constructor属性
,它指回构造函数本身
主要用来记录该对象引用于哪个构造函数
,让原型对象重新指向原来的构造函数。
{: height=”63%” width=”88%”}
原型链
是对象就会有__proto__原型
,指向原型对象
原型对象this指向
构造函数
里面的this
指向的是对象实例ldh
原型对象函数
里面的this
指向的是对象实例ldh
,Star.prototype.sing=function(){this};
原型对象的应用:扩展内置对象方法
比如给数组增加自定义的求偶数和功能
{: height=”63%” width=”68%”}
继承
ES6之前并没有给我们提供extends
继承,我们可以通过构造函数+原型对象
模拟实现继承,被称为组合继承。
call
:调用
这个函数并且修改函数运行时的this指向
fun.call(thisArg,arg1,arg2, ...)
thisArg
当前调用函数this的指向对象
利用父构造函数继承属性
通过call()
把父类型的this指向子类型的this
,这样就可以实现子类型继承父类型的属性
{: height=”63%” width=”68%”}
利用原型对象继承方法
{: height=”68%” width=”78%”}
ES5中的新增方法
数组方法
遍历方法:forEach()
,map()
,filter()
,some()
,every()
1.array.forEach(function(currentValue, index, arr), thisValue)
为每个数组元素调用函数。
currentValue
必需。当前元素的值。index
可选。当前元素的数组索引。arr
可选。当前元素所属的数组对象thisValue
可选。要传递给函数以用作其this
值的值。
2.array.filter(function(currentValue, index, arr), thisValue)
使用数组中通过测试的每个元素创建新数组。主要用于筛选数组
,返回包含满足条件元素
的新数组
。
currentValue
必需。当前元素的值。index
可选。当前元素的数组索引。arr
可选。当前元素所属的数组对象thisValue
可选。要传递给函数以用作其this
值的值。
3.array.some(function(currentValue, index, arr), thisValue)
检查数组中的任何元素是否通过测试。返回布尔值
,查找到这个元素true
,否则false
一旦找到第一个满足的元素之后return true
就可以不再进行查找了
currentValue
必需。当前元素的值。index
可选。当前元素的数组索引。arr
可选。当前元素所属的数组对象thisValue
可选。要传递给函数以用作其this
值的值。
forEach
和some
的区别
forEach
里面的return
不会终止迭代some
里面遇到return true
就会终止遍历,迭代效率更高。且更适用于查找唯一值元素。
字符串方法
str.trim()
删除字符串两端空白字符,返回新字符串
input.value.trim()===''
说明表单无内容
对象方法
Object.keys(obj)
用于获取对象自身所有的属性
,效果类似for...in
,返回数组
Object.defineProperty(obj,prop,descriptor)
定义对象中新属性
或修改原有的属性
。
obj
,必需。目标对象prop
,必需。需定义或修改的属性名字descriptor
,必需。目标属性所拥有的特性。以对象形式{}
书写。value
:设置属性的值
,默认为undefinedwritable
:值是否可以重写
。true|false,默认为falseenumerable
:目标属性是否可以被枚举
,true|false,默认为falseconfigurable
:目标属性是否可以被删除
或是否可以再次修改特性
true|false,默认false
函数进阶
函数的定义
函数也属于对象
- 函数声明方式
function
关键字(命名函数)function fn(){};
- 函数表达式(匿名函数)
var fun = function(){};
- (较少用)利用
new Function('参数1','参数2','函数体'); ()内必须是
字符串`
this
函数内部的this指向
改变函数内部的this指向
call
方法:主要作用是实现继承
。调用函数,可以改变this指向
fn.call(thisArg,arg1,arg2,...)
apply
方法:主要作用是借助数学内置对象求数组最大或最小值
。调用函数,可以改变this指向
fn.apply(thisArg,[argsArray])
,argsArray
必须是数组(伪数组)。虽然传递进来的是数组,但是内部会转换为你想要的数据格式,比如 [1,2,3] ,max拿到的其实是数字1,2,3
var max= Math.max.apply(Math,arr);
求数组最大值- 用得最多:
bind
方法:不会调用
函数,但是会改变this
指向
fn.bind(thisArg,arg1,arg2,...)
返回由指定的this
值和初始化参数改造的原函数拷贝
比如改变定时器
内部的this
指向
严格模式
- 为整个脚本开启严格模式,在所有语句之前放一个特定语句
'use strict';
- 给某个函数开启严格模式,在函数体所有语句之前放
'use strict';
严格模式中的变化
- 变量必须先声明再使用
- 不能随意删除已经声明好的变量
- 全局作用域的函数中的
this
是undefined
,fucntion fn(){console.log(this);}
- 如果构造函数不加
new
调用,this
会报错 - 定时器
this
还是window
,new
实例化的构造函数指向实例对象,事件、对象还是指向调用者 - 函数不能有重名的参数
- 函数必须声明在顶层,新版本的JavaScript会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。
if(true){function f(){}}是错误的
高阶函数
接收函数作为参数或将函数作为返回值输出。
变量作用域
- 函数内部可以使用全局变量
- 函数外部不能使用局部变量
- 当函数执行完毕,本作用域内的局部变量会销毁。
闭包,延伸了变量的作用范围
闭包
指有权访问另一个函数作用域中变量的函数
。
闭包函数
是被访问局部变量所在的函数
- 作用:可以
在fn外面的作用域访问fn内部的局部变量
- 经典问闭包面试题:循环注册点击事件。利用闭包的方式点击小li得到当前小li的索引号
- 闭包案例:定时器中的闭包
- 闭包案例:计算打车费用
- 立即执行函数内的
this
指向window
正则表达式
- 正则表达式里面不需要加引号,无论是数字型还是字符串型
创建正则表达式
- 通过调用RegExp对象来创建
var regexp = new RegExp(/123/);
- (常用)利用字面量创建
var rg = /123/;
测试正则表达式 test
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中有匹配的值返回 true ,否则返回 false。
RegExpObject.test(string)
正则表达式中的特殊字符(元字符)
边界符
^
表示匹配行首的文本(以谁开始)$
表示匹配行尾的文本(以谁结束)- 如果
^
和$
在一起,表示必须是精确匹配
字符类[ ] 表示有一系列字符可供选择,只要匹配其中一个
即可。即加了中括号都是匹配1个
var rg= /[abc]/
只要包含有a 或者包含有b 或者包含有c 都返回truevar rg= /^[abc]$/
只有是a 或者是b 或者是c 才返回truevar rg= /^[a-z]$/
是26个英文字母中任何一个字母都可以返回true-
字符组合
var reg= /^[a-zA-Z]$/
是26个英文字母中任何一个字母的大写或小写都可以返回true -
如果中括号里面有
^
表示取反
的意思。千万与边界符的^
区分开/^[^abc]$/.test('a') // false
量词符 用来设定某个模式出现的次数
量词 | 说明 |
---|---|
* |
重复>=0次 |
+ |
重复>=1次 |
? |
相当于0||1 |
{n} |
重复n次 |
{n,} |
重复>=n次 |
{n,m} |
重复n到m次 |
var reg= /^[a-z]{6,16}$/;
注意{n,m}
中间千万不能有空格
括号总结
- 在线测试正则式工具
大括号{}
量词符,里面表示重复次数
中括号[]
字符集合,匹配方括号中的任一字符
小括号()
表示优先级
预定义类(某些常见模式的简写方式)
预定类 | 说明 |
---|---|
\d |
相当于[0-9] |
\D |
相当于[^0-9] |
\w |
相当于[A-Za-z0-9] |
\W |
相当于[^A-Za-z0-9] |
\s |
相当于[ \t\r\n\v\f] |
\S |
相当于[^ \t\r\n\v\f] |
replace
替换字符串,替换的参数可以是一个字符串或是一个正则表达式
stringObject.replace(regexp/substr,replacement)
第一个是被替换,第二个是替换为。返回一个替换完毕的新字符串
var str= 'andy、andy、red'; var newStr= str.replace(/andy/,'baby')
但是单纯这样匹配,只能替换掉第一个andy
正则替换 正则表达式参数
switch(修饰符)
说明按照什么样的模式来匹配,有三种值。replace(/激情|gay/g,'**')
把全部的激情
或者gay
都换为**
g
:全局匹配i
:忽略大小写gi
:全局匹配+忽略大小写
ES6的let
、const
let
let
声明的变量只在所处于的块级有效if(true){let a=10;};console.log(a)//a undefined
(var不具备这个特点)- 使用
let
声明的变量不存在变量提升(这本来就是语言的糟粕) - 使用
let
声明的变量具有暂时性死区的特性
var num= 10;
if(true)
{
console.log(num); //报错,undefined。和上面那个var num没有任何关系
let num= 20; //这个变量会和这个块级作用域整体进行绑定
}
- 经典面试题1
- 经典面试题2
循环时是为arr[i]添加一个函数地址,但是并没有调用该函数
,循环后调用,此时的 i 都是2
此题关键点在于变量 i 是全局的,函数执行时输出的都是全局作用域下的 i 值。
const
声明常量,常量就是值(内存地址)不能变化的量
- 特点:具有
块级作用域
- 声明常量时必须赋初值
const PI= 3.14
- 常量赋值后,值不能修改
const PI =3.14;
PI= 100; //不可以!!!
cosnt ary= [100,200];
ary[0]='a';
ary[1]='b';
console.log(ary); //['a','b'];
ary= ['a','b']; //不可以!!!
ES6解构赋值
按照一定模式,从数组中或对象中提取值,将提取出来的值赋值给另外的变量。
数组解构 这里的 [ ] 不代表数组,它代表解构,它代表从数组中提取值
let[a,b,c]=[1,2,3];
注意要使用let
关键字- 如果解构不成功,变量的值为undefined
let [bar,foo]= [1];
对象解构
- 把对象的属性赋值给给变量
let person= { name:'zhangsan',age:20 }; let { name,age }= person;
let {name:myName, age:myAge}= person; // myName myAge 属于别名
console.log(myName); // 'zhangsan'
console.log(myAge); // 20
ES6箭头函数 新增的定义函数的方式
let fn= ()=>{}
- 如果函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
let sum = (num1,num2)=> num1+num2;
- 如果形参只有一个,可以省略小括号
let fn = v => v
箭头函数中的this关键字
箭头函数不绑定this关键字,箭头函数中的this
,指向的是函数定义位置的上下文this
箭头函数面试题
剩余参数
允许我们将一个不定数量的参数表示为一个数组
剩余参数和解构配合使用
Array的扩展方法
扩展运算符(展开语法) 将数组或对象转为用逗号分隔的参数序列
- 注意输出结果不带逗号,因为
console.log()
将逗号作为分隔符
Array
实例方法
ES6模板字符串
set
数据结构