js-25继承闭包及练习题
01继承
1.继承引入 - 是类与类之间的关系 子类继承父类子类就拥有父类的属性和方法【重点】 2.es5:继承语法 1.call函数继承-构造函数继承(继承属性) 在子类的构造函数中使用 父类构造函数的call函数实现继承 Person.call(this,name,age) //构造函数继承 原理: call函数改变this 2.继承原型属性方法 拷贝继承 父类原型上的属性和方法复制拷贝到子类原型对象上 遍历父类原型所有属性和方法,执行拷贝 3.原型链实现原型对象属性和方法->原型继承 4.构造函数继承+原型继承 = 组合继承 子类继承父类属性和方法包括原型对象上的 3.es6:继承语法 语法: class 父类{ constructor(){ } } class 子类 extends 父类{ //继承 constructor(){ super() //调用父类构造器 //子类属性定义 } } let 子类实例 = new 子类()
//父类 function Person(name, age) { this.name = name this.age = age } Person.prototype.say = function () { console.log(this.name, '说话'); } let p1 = new Person('jack', 18) console.log(p1.name, p1.age); // p1.say() //子类 function Student(name, age, num) { Person.call(this, name, age) //构造函数继承 this.num = num } // Student.prototype.say = Person.prototype.say //拷贝继承 for(let key in Person.prototype){ Student.prototype[key] = Person.prototype[key] } let s1 = new Student('jack', 18, 1001) console.log(s1.name, s1.age, s1.num); s1.say() --------------------------------------------------------------------------- //父类 function Person(name, age) { this.name = name this.age = age } Person.prototype.say = function () { console.log(this.name, this.age,'说话'); } //子类 function Student(name, age, num) { Person.call(this, name, age) //构造函数继承 this.num = num } //原型链实现原型对象属性和方法->原型继承 Student.prototype = new Person() let s1 = new Student('tom', 20, 1001) s1.say() ---------------------------------------------------------------------------- class Person{ constructor(name,age){ this.name = name this.age = age } say(){ console.log(this.name,this.age,'说话'); } } // let p1 = new Person('jack',18) // p1.say() //子类Student继承父类Person // super() class Student extends Person{ constructor(name,age,num){ super(name,age) //super表示调用父类构造器 this.num = num } } let s1 = new Student('rose',20,1001) // console.log(s1.name,s1.age,s1.num); s1.say()
02闭包
![函数不被销毁的执行空间](D:\周sir\课件\week6-jquery\函数不被销毁的执行空间.png)回顾函数 function fn(){ } let fn1 = function(){ } (function(){ })() let fn2 = new Function() 1.函数执行空间 - 执行栈 | 调用栈 理解:函数作为复杂数据类型储存在堆区,调用的时候,在调用栈中将其复制运行,运行结束后,自动销毁。 2.函数不被销毁的空间 -函数体返回一个复杂数据类型,被外部使用,这时候,函数执行空间不被销毁 function fn(){ let num = 100 return {name:'jack'} //1.复杂数据类型 } let f = fn() //2.外部使用
闭包: 一种语法,函数的高级用法. 闭包形式成条件 1. 有函数嵌套 2. 内部函数使用外部函数私有变量 3. 内部函数被返回在外部使用 闭包作用: 1. 生成一个不被销毁的执行空间, 缺点: 引起内存泄露问题 特点: 形成块作用域 2. 外部函数可以访问内部函数的变量 作用域: 内部函数可以访问外部函数变量 3. 保护私有变量 优点: 可以把一些变量放在函数里面,不会污染全局 缺点: 要利用闭包函数才能访问,不是很方便 闭包写法:
闭包三种写法: 方法1: function fn1(){ var num = 1; return function(){ console.log(num); } } let f1 = fn1() f1() 方法2: let fun; function fn(){ var num=2; fun = function(){ console.log(num); } } fn() fun() 方法3: let f3 = (function(){ var num=3; return function(){ console.log(num); } })() f3()
03闭包题
//1.明星点赞 const liBtns = document.querySelectorAll('ul>li>button') for (let i = 0; i < liBtns.length; i++) { // let num = 0; //1.let块作用域 // function fn() { //2.闭包 // var num = 0; // liBtns[i].addEventListener('click', function () { // this.innerHTML = '点赞 ' + ++num; // }) // } // fn() (function () { //2.2闭包第二种写法 var num = 0; liBtns[i].addEventListener('click', function () { this.innerHTML = '点赞 ' + ++num; }) })() } //2.【考试题】 function getCounter(){ let counter = 0; return function(){ return counter+=1 } } let f1 = getCounter() console.log(f1()); //1 console.log(f1()); //2 console.log(getCounter()()); //1 console.log(getCounter()()); //1
作业: 1. 预习jquery 2. 选项卡练习复习 (明天jquery实现) 3. todolist应用
.log(f1()); //1
console.log(f1()); //2
console.log(getCounter()()); //1 console.log(getCounter()()); //1
作业: 1. 预习jquery 2. 选项卡练习复习 (明天jquery实现) 3. todolist应用