js的闭包
闭包的本质:外层函数套内层函数,内层函数作为外层函数的return语句的返回值。在外层函数里声明一个局部变量,在内层函数里操作并返回这个局部变量。外层函数自调用将返回值也就是内层函数的引用赋值给一个变量(内层函数)。此时调用该变量就等价于调用内层函数,也就可以操作原本外层函数的局部变量了。并且想要获取或操作刚刚那个局部变量,执行内层函数将是唯一的一个途径。
闭包缺陷:因为该局部变量不会被JS的垃圾回收机制所自动回收,所以当大量使用闭包并且闭包内得的局部变量足够多时,就容易爆掉用户的内存(内存泄漏)。
使用场景:
1.如果希望一个局部变量可以在函数体外部操作访问到。
2.如果希望某一个变量只能通过调用某一个函数的形式进行修改。
js的继承在面试题中的问法:
* 如果在js中实现面向对象中的继承。
* call和apply这两个方法有什么不同点。
js继承的实现机制:在子类中继承父类的私有属性和私有方法使用call或apply的方法来在子类函数中调用父类函数并改变this指向。如果想在子类中继承父类的原型属性和原型方法的话,这种需求方法有很多种,问题最少的是使用原型链的方式进行进行继承,具体的操作就是将父类的实例化对象赋值给子类的原型对象,此时子类的实例化对象在调用父类的原型方法或原型属性时,虽然在子类的原型对象中找不到对应的属性或方法,但是在子类的原型对象中的原型对象中可以找到这些方法。并且子类独有的原型属性和原型方法不会影响到父类。
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
type:"灵长类",
sayName(){
alert(this.name)
}
}
let wdw = new Person("王大伟",18,"男");
function SuperMan(name,age,sex,skill){
Person.apply(this,[name,age,sex]);
this.skill = skill;
}
SuperMan.prototype = new Person();
SuperMan.prototype.showSkill = function(){
alert(this.skill)
}
let spiderMan = new SuperMan("蜘蛛侠",18,"男","爬墙");
spiderMan.constructor = SuperMan;
console.log(spiderMan)
ES6实现继承
class Person{
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
sayName(){
alert(this.name)
}
}
let wdw = new Person("王大伟","18","男")
console.log(wdw)
class SuperMan extends Person{
constructor(name,age,sex,skill){
super(name,age,sex)
this.skill = skill
}
skill(){
alert(this.skill)
}
}
let cr = new SuperMan("超人",18,"女","飞")
console.log(cr)