文章目录
前言
今天我们主要学习闭包,柯里化函数、继承三个知识点,闭包是函数的一种高级使用方式,是javascript的语法现象,闭包形成后会生成一个不会被销毁的函数执行空间;柯里化(Currying)是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。继承是类与类之间的关系,子类继承父类子类就拥有父类的属性和方法
一、闭包
1)闭包概念
闭包 是我们函数的一种高级使用方式,是javascript的语法现象,在学习闭包之前我们要先回顾一下函数。
函数主要有两个阶段:定义阶段和调用阶段
函数的三种定义方式:
①函数声明定义式 function fun(){ }
②赋值式 let fun=function(){ }
③函数为对象 let fun = new Function('console.log("内容")')
1.函数执行空间与不销毁的函数执行空间
函数执行空间:
不销毁的函数执行空间
以上函数执行空间与不销毁的函数执行空间 就是普通函数与闭包的区别,函数执行空间是普通函数被调用时的结构图,而不销毁的函数执行空间就是闭包调用时的结构图。
2.闭包形成条件
闭包形成后:
①生成一个不会被销毁的函数执行空间,
② 内部函数叫做外部函数的闭包函数
闭包形成条件:
1. 函数嵌套- 外层函数 内层函数
2. 外部引用返回的内层函数
3. 内层使用外层函数变量
3.闭包作用
闭包作用:
1. 形成不被销毁的执行空间,延长变量生命周期, 缺点,容易引起内存泄露
2. 外部可以访问内部函数的变量- 变量作用域扩展 - 没有形成闭包,只能内部函数访问外层函数变量
3. 形成块作用域定义私有变量
2)闭包的三种写法
1.显示写法
2.隐式写法
3.自调用函数
3)闭包的特点
1. 作用域空间不销毁
优点: 因为不销毁,变量不会销毁,增加了变量的生命周期
缺点: 因为不销毁,会一直占用内存,多了以后就会导致内存溢出
2. 可以利用闭包,在一个函数外部,访问函数内部的变量
优点: 可以在函数外部访问内部数据
缺点: 必须要时刻保持引用,导致函数执行栈不被销毁
3. 保护私有变量
优点: 可以把一些变量放在函数里面,不会污染全局
缺点: 要利用闭包函数才能访问,不是很方便
二、柯里化函数
柯里化(Currying)是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。
柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。柯里化不会调用函数。它只是对函数进行转换。
柯里化:
柯里化函数
将有多个形参的函数转换成多个只有一个形参的函数
f(a,b,c) -> fn(a)
fn1(b)
fn2(c)
f(a,b,c) -> fn(a)(b)(c)
高级柯里化实现:
柯里化函数实例:
function sum(a,b,c,d){
return a + b + c + d
}
function currying(func){ // func -> sum
// ...args 表示可变长度形参
return function curried(...args){
// 判断形参args个数>= 原函数参数个数func
if(args.length >= func.length){
return func.apply(this,args) //sum(10,20,30)
}else{
return function(...arg2){
// 参数拼接
let arg = [...args,...arg2] // -> [10,20,30]
return curried.apply(this,arg)
}
}
}
}
let f = currying(sum) // f(10,20,30)
// let s = sum(10,20,30)
let s = f(10)(20)(30)(40)
console.log('s :',s) //输出位100
三、继承
1)继承概念
继承引入:
面向对象三大特性之一 继承
1. 封装 对象属性和方法
2. 继承
3. 多态 一个事物有多种表现形态
let num = 100 // number
num = '100' // string
面向对象的世界里,一切即对象.
每个对象都有自己的属性和方法.
根据不同对象的属性和方法,将对象分成不同类型
比如: 人类: 有眼睛,鼻子,耳朵,能说话
手机:能打电话,发短信
学生类: 能读书,写字
继承 是类与类之间的关系,子类继承父类子类就拥有父类的属性和方法
比如: 学生类继承人类就拥有人类的属性和方法,学生类称为子类,人类称为父类
继承中子类与父类概念:
我们先准备一个父类(也就是要让别的构造函数使用我这个构造函数的属性和方法)
这个 Person 构造函数为父类,让其他的构造函数来继承他,当别的构造函数能够使用他的属性和方法的时候,就达到了继承的效果
2)实现继承的方式
1.构造函数继承,继承父类构造函数属性和方法
2.原型拷贝继承,继承父类原型对象上公共的属性和方法
3.ES6 的类与继承
继承案例
定义一个人类Person,有姓名name,性别sex属性,有吃饭eat方法
定义一个驾驶员类Driver,有驾龄driverTime属性,有驾驶开车方法 onOpenCar
定义一个老师类Teacher, 有教龄teachTime属性,有教学上课方法 onTeache
要求: 驾驶员和老师继承人类,
实例化名为 张三性别为男的驾驶员,调用其开车功能,
实例化名为 zhousir性别为男的讲师,调用其上课功能
class Person{
constructor(name,sex){
this.name=name
this.sex=sex
}
eat(){
console.log('吃饭')
}
}
//驾驶员类Driver
class Driver extends Person{
constructor(driverTime,name,sex){
super(name,sex)
this.driverTime=driverTime
}
onOpenCar(){
console.log('驾驶开车')
}
}
//老师类Teacher
class Teacher extends Person{
constructor(teachTime,name,sex){
super(name,sex)
this.teachTime=teachTime
}
onTeache(){
console.log(`教学上课`)
}
}
// 实例化名为 张三性别为男的驾驶员,调用其开车功能,
// 实例化名为 zhousir性别为男的讲师,调用其上课功能
var Person1=new Person()
var Driver1=new Driver('3年','张三','男')
let Teacher1=new Teacher('4年','zhousir','男')
console.log(Driver1.name,Driver1.sex)
Driver1.onOpenCar()
console.log(Teacher1.name,Teacher1.sex)
Teacher1.onTeache()
运行结果: