DAY22JS学习--闭包、柯里函数、继承

一、函数内存结构

1、函数声明

(1) 解析到函数声明语句时,相当于创建一个函数对象

(2)函数体中的代码会以字符串的形式存储到堆区域

(3) 将函数体堆区域的地址复制给函数名

2、函数调用

(1)根据函数名找到函数体在堆区域代码

(2)复制函数体代码到调用栈区域执行

(3)执行完毕销毁调用栈

二、函数不被销毁的执行空间

1、函数调用时,函数体代码返回一个复杂数据类型对象,赋值给一个变量,该变量引用函数体复杂数据类型,调用栈空间不会被销毁

 三、闭包

1、闭包形成的条件

(1)函数嵌套:外层函数嵌套内层函数

(2)外部引用返回的内层函数

(3)内层函数使用外层函数的变量

function fun(){
   let num=100
    //内层函数
   return function(){
    console.log('num',num) //内层使用外层函数变量
}

}

let f=fun() //外部引用返回的内层函数
f()

2、闭包作用

(1)形成不被销毁的执行空间,延长变量生命周期

缺点:容易引起内存泄露

(2)外部可以访问内部函数的变量---变量作用域扩展

(3)形成块级作用域定义私有变量

块级作用域:多次调用,函数体多次复制到调用栈,互不干扰

四、闭包的三种写法

1、显示写法

function A(){
  let num=100
  return function B(){
    console.log(num)
  }
}

let f=A()

2、隐式写法

let B
function A(){
  let num=100
  B=function(){
    console.log(num)
  }
}

A()
B()

3、自调用函数

let x=(function(){
   let num =100
   return function B(){
     console.log(num)
   }
})()

五、柯里化函数

1、定义
将有多个形参的函数转换为多个只有一个形参的函数

f(a,b,c)=>fn(a)(b)(c)

2、通用柯里化函数

 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);

六、继承

1、面向对象三大特性

(1)封装:对象属性和方法

(2)继承:子类继承父类,子类就拥有父类的属性和方法

(3)多态:一个事务有多种表现形态

2、ES5实现继承

(1)构造函数继承(不能继承父类原型对象上的属性和方法)---在子类构造函数中调用父类构造函数  

(2)拷贝继承-实现原型属性和方法继承

// 父类
			function Parent() {
				this.money = 100000
				this.home = '房子'
				this.playGame = function () {
					console.log('玩游戏')
				}
			}
            Parent.prototype.swiming = function(){
                console.log('游泳');
            }
            
			// 子类
			function Son() {
                // 构造函数继承
                Parent.call(this)
                this.name = 'jack'
			}

            // 拷贝继承-实现原型属性和方法继承
            for(const key in Parent.prototype){
                Son.prototype[key] = Parent.prototype[key]
            }
            
            let parent1 = new Parent() // parent1是有money和房子的父类实例对象
			let s1 = new Son() // 名为jack的儿子实例对象

            // 测试儿子是否继承到父类属性和方法
            s1.playGame()
            console.log(s1.money, s1.home);
            s1.swiming()

(3)原型继承

// 父类
			function Parent() {
				this.money = 100000
				this.home = '房子'
				this.playGame = function () {
					console.log('玩游戏')
				}
			}
            Parent.prototype.swiming = function(){
                console.log('游泳');
            }
            
			// 子类
			function Son() {
                this.name = 'jack'
			}

            // 原型继承 - 改变原型指向实现 - 将父类实例复制子类原型对象
            Son.prototype = new Parent()

            
            let parent1 = new Parent() // parent1是有money和房子的父类实例对象
			let s1 = new Son() // 名为jack的儿子实例对象

            // 测试原型继承
            s1.swiming()
            s1.playGame()
            console.log(s1.money, s1.home);

(4)组合继承

构造函数+拷贝继承

3、ES6实现继承

(1)class类继承

(2)语法

// 父类
			class Parent {
				constructor() {
					this.money = 100000
					this.home = '房子'
				}
                playGame(){
                    console.log('玩游戏');
                }
                swiming(){
                    console.log('游泳');
                }
			}

            // 子类Son继承父类Parent
            class Son extends Parent{
                constructor(name){
                    // 先实例化父类
                    super() //super关键字表示父类构造器
                    this.name = name
                }
            }

            let parent1 = new Parent()
            let son1 = new Son('jack')

            son1.swiming()
            son1.playGame()
            console.log(son1.money, son1.home);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值