0
点赞
收藏
分享

微信扫一扫

JS 闭包和继承

琛彤麻麻 2022-04-14 阅读 151
1.继承

继承 是类与类之间的关系
子类继承父类子类就拥有父类的属性和方法

1.JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承

父类

//人类-父类
function Person(){
this.name 'jack'
this.age 20
}
Person.prototype ={
    constructor:Person,
    //手动设置constructor:指向构造函数
say:function(){
console.log('说话')
	}
}

子类

//学生-子类
function Student(){
		this.num=1081//学生学号
}
Student.prototype={
	constructor:Student,
	//读书
readBook:function(){
console.log('学生读书)
        }
   }
构造函数继承
继承父类构造函数属性和方法
//学生-子类
function Student(){
Person.call(this)//构造函数继承,继承父类构造函数属性和方法
this.num=1001字生学号
}
原型拷贝继承
继承父类原型对象上公共的属性和方法
//拷贝继承,继承父类原型对象上公共的属性和方法
for(let key in Person.prototype){
Student.prototype[key]=	Person.prototype[key]
}

2.ES6 的类与继承

class类名{
//构造函数
constructor(name){
this.name=name
}
//方法
say(){}

}
·es6的继承很容易,而且是固定语法
//下面表示造一个Student类,继承自Person类
class Student extends Person{
constructor (){
//必须在constructor里面执行一下super()完成继承
super()
}
}
·这样就继承成功了
 ES6语法
创建对象>class
//人类
class Person{
	constructor(name,age){
		this.name = name
        this.age = age
    }
	say(){
	console.log(this.name,"在说话")
    }
}
//学生类
class Student extends Person{
		constructor(name, age ,num){
		super(name,age)// super表示调用父类构造函数
        this.num = num
        }
	readBook(){
		console.log("学号是" ,this.num,"的学生在读书")
    }
}
let s1 = new Student( "jack ",23,1081)
s1.say()
console.log(s1.name,s1.age,s1.num)
2.闭包

函数的两个阶段

  • 定义阶段
  • 调用阶段

函数执行空间

当js引擎解析到fn函数定义时,
=>在堆区域开辟一块存储空间,将函数体内代码以字符串形式存储到堆区域
=>在栈区域存储fn函数变量,并将堆区域存储空间地址赋值给fn
function fn(){
let num = 100
console.log ( 'fn函数' , num)
*当执行函数调用语句fn()时,
=>根据fn找到堆区域函数体代码,复制一份到调用栈区域,
=>执行调用栈函数体代码,执行完毕销毁调用栈区域
fn()

不销毁的函数执行空间

当js引擎解析到fn函数定义时,
=>在堆区域开辟一块存储空间,将函数体内代码以字符串形式存储到堆区域
=>在栈区域存储fn函数变量,并将堆区域存储空间地址赋值给fn
function fn(){
let num = 100
	console.log( 'fn函数' , num)
   return {}
}
当执行函数调用语句fn()时,*
=>根据fn找到堆区域函数体代码,复制一份到调用栈区域,
=>执行调用栈函数体代码,
=>函数体代码返回一个复杂数据类型,赋值给变量f
=>f引用函数体复杂数据类型对象,调用栈空间不会销毁
let f = fn()

了解闭包

闭包条件:
1.有一个A函数,在A函数内部返回一个B函数
2.在B函数内部,访问A函数私有变量
3.在A函数外部,有一个变量引用返回的B函数
function A() {
let num = 106
//1.A函数内部返回一个B函数(显示)
return function B() {
	console.log(num)//2.B函数内部,访间A函数私有变量num
	}
}
let f = A()// 3变量f引用返回的B函数

闭包形成后:

  • 生成一个不会被销毁的函数执行空间,
  • 内部函数叫做外部函数的闭包函数

闭包概念

  1. 有一个A函数,在A函数内部返回一个B函数

  2. 在B函数内部,访问A函数内部私有变量

  3. 在A函数外部,有一个变量引用返回的B函数

  4. 有函数嵌套,内层函数被返回

  5. 内层函数访问外层函数私有变量

  6. 返回的内层函数被引用

闭包三种写法

1.显示写法

function A() {
let num = 100
//1.A函数内部返回一个B函数(显示)
	return function B() {
		console.log(num)//2.B函数内部,访问A函数私有变量num
	}
}
let f = A()3.变量f引用返回的B函数

2.隐式写法

let B // 3.在A函数外部,有一个变量引用返回的B函数
function A() {
	let num = 280
	//1.A函数内部返回一个B函数(隐示)
    B= function () {
		console.log(num)//2.B函数内部,访间A函数私有变量num
		}
}
A()
B()

3.自调用写法

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

闭包的特点

  1. 作用域空间不销毁
    优点: 因为不销毁,变量不会销毁,增加了变量的生命周期
    缺点: 因为不销毁,会一直占用内存,多了以后就会导致内存溢出

  2. 可以利用闭包,在一个函数外部,访问函数内部的变量
    优点: 可以在函数外部访问内部数据
    缺点: 必须要时刻保持引用,导致函数执行栈不被销毁

  3. 保护私有变量
    优点: 可以把一些变量放在函数里面,不会污染全局
    缺点: 要利用闭包函数才能访问,不是很方便

举报

相关推荐

0 条评论