JavaScript闭包、原型链、继承 ——总结

面试回答技巧(一)
如何回答的一个技术记汇,或者你对xxxx的理解?
例如:你说一下对闭包的理解?
:1.xxx是什么?
2.应用场景
3.优缺点
4.具体实现
5.还有没有更好的解决方案!

今天的内容都是从这几个方面来讲解。

一、闭包

1、闭包是什么?

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。

总结来说:闭包就是函数加词法作用域。只要符合这两种情况基本上都是闭包。

那么什么是词法作用域呢?这里就来说说,看下面的代码:

function init() {
    var name = "张三"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}
init();

init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init()函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以displayName() 可以使用父函数 init() 中声明的变量 name

总结:
词法作用域:即以变量声明定义的位置为参照,如果当前位置没有定义,就会访问父级定义的位置。

闭包又分为广义和狭义两种:

a、广义的闭包:

var a=1000;
function fn1() {
   alert(a)
}
fn1()

b、狭义的闭包:

平时工作中用到的闭包是狭义上的闭包:

1.函数内嵌套函数
2.子函数引用了父函数的相关变量

符合上面的条件都是狭义的闭包。

特点:长期驻留内存

2、闭包的应用场景和怎么实现?

//求和
function makeAdd(x) {
    return function(y) {
     return x+y
   }
}

//设置字号
function setFontSize(size) {
   return function() {
     document.body.style.fontSize=size+"px"
   }
}

//循环表单
function makeHelp(help) {
    return function() {
       console.log(help)
        document.querySelector('.help').innerHTML=help
    }
 }
function init() {
    var userInfo=[
        {id:'username',helpText:'请输入用户名'},
        {id:'email',helpText:'请输入邮箱'},
        {id:'address',helpText:'请输入地址'},
    ]
    //动态绑定onfocus事件
    for(var i=0;i<userInfo.length;i++) {
        var item=userInfo[i];
        document.getElementById(item.id).onfocus=makeHelp(item.helpText)

    }
}
init()

//封装组件或插件
var Counter=(function() {
   //私有变量
   var index=0;
   //私有方法
   var add=function() {
       return index++;
   }
   var jian=function() {
   
   }
   return {
       //暴露出去供用户的方法
       increment:function() {
           add()
       },
       getValue:function() {
           return index;
       }
   }
})()

3、闭包的优缺点

优点:

1.长期驻留内存,可以缓存数据
2.可以隔离作用域,避免全局污染

缺点:

长期使用,会造成内存泄漏。

解决内存泄漏的方法:
链接:https://www.jianshu.com/p/d903be89f211
上面的链接,自我感觉可以。

4、最好的解决方案

使用ES6的let方法,可以有效的避免。

二、原型链

https://www.jianshu.com/p/08c07a953fa0

1、原型链是什么?

每个对象都可以有一个原型_proto_,这个原型还可以有它自己的原型,以此类推,形成一个原型链。查找特定属性的时候,我们先去这个对象里去找,如果没有的话就去它的原型对象里面去,如果还是没有的话再去向原型对象的原型对象里去寻找… 这个操作被委托在整个原型链上,这个就是我们说的原型链了。

  • 原型链是JS特有的一种继承机制。
  • 原型链会涉及到__proto__,prototype。
  • 原型链的顶端就是null。

2、原型链的主要应用场景

继承

3、优点和缺点

  • 优点:把相同或类似的方法写在原型上,方便实例化对象复用
  • 缺点:不好理解,通常只前端人才理解

4、解决方案

ES6推出class extends来实现继承。

三、JavaScript继承

1、继承是什么?

继承是面向对象开发思想的特性之一。
面向对象的三大特点:封装、继承、多态(多种状态)。

2、实现方式(有两种)

a、ES5继承(主要通过函数来实现类)
  • 原型链继承
//创建一个父类
function Parent() {
    this.name='jack'
}
Parent.prototype.getName=function() {
    return this.name;
}
//创建一个子类
function Child() {
 
}
//子类的原型等于父类的实例化对象
Child.prototype=new Parent();
var c1=new Child()

缺点:
1、不能传参
2、 没有解决对象引用问题

  • 借用构造函数继承
//创建一个父类
function Parent(name) {
    this.name=name ||'jack'
    this.colors=['red','green','blue']

}

Parent.prototype.getName=function() {
    return this.name;
}

//创建一个子类
function Child(name) {
    //借用父类来承继实例属性,但不能继承父类方法
    Person.call(this,name)
    
}

缺点:不能继承父类方法

  • 组合继承(原型链继承 + 借用构造函数)
//创建一个父类
function Parent(name) {
    this.name=name ||'jack'
    this.colors=['red','green','blue']

}

Parent.prototype.getName=function() {
    return this.name;
}

var p1=new Parent();
p1.getName();


//创建一个子类
function Child(name) {

    Parent.call(this,name)
    
}

Child.prototype=new Parent();

var c1=new Child()
c1.getName()

优点:既能继承父类的原型和方法,也能传递参数属性。

b、ES6继承

通过class,extends,super实现 //继承必须要写super

//创建一个父类
class Parent {
   constructor(name) {
        this.name=name ||'jack'
        this.colors=['red','green','blue']
   }
  getName() {
    return this.name;
  }
}
//创建一个子类
 class Child extends Parent {
      constructor(name) {
          super(name)  //super就是父类Parent
      }
      getValue() {

      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值