一、什么是闭包?

    (1)闭包的概念:a、闭包就是函数嵌套时,让局部变量变成自由变量的环境,是一种让局部变量进化的方式。
 
                   b、定义在一个函数内部的函数。
    
    (2)垃圾回收机制:用过一次的东西,先放在一个内存中,不立即删掉,可以随时进行还原或再次使用,直到没有任何作用的时候再清除。
      tip: 如家用电器,电脑回收站。
 
二、闭包的应用场景:
        //1、for循环之中:
// for循环之中的i变量会因为for的循环次数被覆盖,所以在for循环内部存在函数时,而且这个函数内会调用i变量,这种情况下就需要用到闭包。 for (var i = 0; i < 10; i++) {
console.log(i); //可以访问到每次的i
} // 必须满足两个条件:
// 1.在for循环内存在函数
// 2.函数内会调用这个变量 var ali = document.getElementsByTagName("li");
for(var i=0;i<10;i++){
ali[i].onclick = function(){
console.log(i); //在函数内部就无法访问到外部变量
}
} // 如何形成闭包
var ali = document.getElementsByTagName("li");
for(var i=0;i<10;i++){
(function(a){
ali[a].onclick = function(){
console.log(a);
}
})(i)
}
// 一旦内部函数调用外部函数的局部变量,那么这个时候,这个局部变量就会变成内部函数的私有变量 // 2、当需要给setTimeout的回调函数传参时:
setTimeout(function (a){
console.log(a); //两秒后,undefined
}, 2000);
// 或者
setTimeout(fn(10), 2000);
function fn(a){
console.log(a); //没有延迟,直接打印10
} // 怎么使用闭包: function fn(a){
return function(){
console.log(a); //两秒后,10
}
}
var f = fn(10);
setTimeout(f, 2000);

三、闭包的特点:

  (1)闭包是将函数内部和函数外部连接起来的桥梁.

  (2)可以读取函数内部的变量。

  (3)让这些变量的值,始终保存在内存中,不会在调用结束后被系统回收。

  (4)避免全局变量命名空间的污染。

  (5)内存消耗很大,不能滥用。

  (6)闭包会在父函数外部,改变父函数内部变量的值。

四、构造函数继承:

        // 在构造函数中,同样属于两个新创建的函数,也是不相等的
function Fn(name){
this.name = name;
this.show = function(){
alert(this.name);
}
}
var obj1 = new Fn("AAA");
var obj2 = new Fn("BBB");
obj1.show()
obj2.show()
// 此时,任何一个new出来的实例上都有了show方法,可以视为最基础的继承。

五、js中的call和apply继承:

        function Father(skill){
this.skill = skill;
this.show = function(){
alert("我会"+this.skill);
}
}
function Son(abc){
//这里的this指向函数Son的实例化对象
//将Father里面的this改变成指向Son的实例化对象,当相遇将father里面所有的属性和方法都复制到了son身上
//Father.call(this,abc);//继承结束,call适合固定参数的继承
//Father.apply(this,arguments);//继承结束,apply适合不定参数的继承
}
var f = new Father("绝世木匠”);
var s = new Son("一般木匠");
f.show()
s.show();
// 优点:
// 创建子类实例时,可以向父类的构造器传参;
// 缺点:
// 只能继承构造器中定义的属性和方法,不能继承原型上定义的属性和方法

六、js中prototype的概念:

  (1)prototype是原型对象

  (2)指针  constructor  表示当前函数属于谁,用来指向当前原型所属的函数

  (3)原型指针  [[prototype]]  __proto__  相当于一根原型指针,指向当前对象的“父级”

  (4)可以在当前函数的原型身上添加各种属性和方法,以供使用

  (5)JS中万物皆对象,所有内容的指针终点都指向Object

七、原型链继承:

        // 方法一:
Son.prototype = new Father();
//创建一个函数Father,用来做原始对象
function Father(){
this.skill = "铁匠"
};
Father.prototype.show = function(){
console.log(this.skill)
}
//创建一个函数Son,准备继承Father的原型
function Son(){};
//将Son点原型,赋值为一个指针,指向Father的原型
Son.prototype = new Father(); //此时就可以通过执行new Son()获取到从构造函数Father上继承过来属性和方法
var s = new Son()
s.show(); //铁匠 // 优点:
// 1.可以访问父类原型上的方法和属性
// 2.简单方便,易于实现 // 缺点:
// 1.创建子类实例时,无法向父类的构造器传参 // 方法二:
//创建一个函数Father,用来做原始对象
function Father(){
this.skill = "铁匠";
};
Father.prototype.show = function(){
console.log("hello world")
}
//创建一个函数Son,准备继承Father的原型
function Son(){};
//将Son的原型,设置为Father的原型
//Son.prototype = Father.prototype;
//但是这种拷贝方式为对象的浅拷贝,一旦后期修改Son原型上的方法,会影响到Father的原型
//需采用对象的深拷贝方法
for(var i in Father.prototype){
Son.prototype[i] = Father.prototype[i];
}
Son.prototype.show = function(){
console.log("这是子类修改之后的show方法")
}
var f = new Father()
f.show()
var s = new Son()
s.show(); // 优点:
// 完全将父类原型上的方法和属性拷贝到子类原型 // 缺点:
// 只能继承原型上的方法和属性,构造函数无法传参和继承

八、混合继承:

        // 特点:
// 使用call或apply继承父类的构造器中的内容,使用原型继承,继承父类的原型
function Father(skill,id){
this.skill = skill;
this.id = id;
}
Father.prototype.show = function(){
alert("我是father,这是我的技能"+this.skill);
} function Son(){
Father.apply(this,arguments);
}
//如果不做Son的原型继承Father的原型,此时会报错:son.show is not a function
for(var i in Father.prototype){
Son.prototype[i] = Father.prototype[i];
}
//因为,如果不让Son的原型等于Father的原型,Son使用apply是继承不到原型上的方法
Son.prototype.show = function(){
alert("我是son,这是我的技能"+this.skill);
}
var f = new Father("专家级铁匠","father");
var s = new Son("熟练级铁匠","son");
f.show();
s.show();

九、ES6中class的继承:

        class Father{
constructor(){
}
show(){
}
} class Son extends Father{
constructor(){
super()
}
show(){
}
}

十、原型对象相关概念解析:

1、对象中的__proto__是什么:
  js中万物皆对象,每个数据都会有一个__proto__的属性,这个属性叫隐式原型,一个对象(obj)的隐式原型(__proto__)指向构造该对象(obj)的构造函数(object())的原型属性(object.prototype),这样做的原因是为了能够保证实例(obj)能够访问到在构造函数(object())的原型属性(object.prototype)中定义的属性和方法。
 
2、函数中的prototype是什么:
  (1)函数(Function)是一个特殊的对象,除了和其他对象一样有上述__proto__属性之外,还有自己特有的属性——原型(prototype),这个属性被描述成指针,他指向一个对象类型的数据,这个对象的用途就是包含所有将来使用该函数构造出来的可被共享的属性和方法(我们把这个对象叫做原型对象)。
  (2)原型对象内也有一个属性,叫做constructor,这个属性包含了一个指针,指回原函数(类似于arguments.callee。但是arguments只能在函数内部获得,而函数原型对象内的constructor属性,可以在任何能访问到这个函数的位置使用)。
 
3、构造函数,原型,实例之间的关系:
  (1)构造函数Fn身上有属性prototype为原型对象,原型对象内有constructor属性指向当前prototype所在的构造函数Fn。
  (2)在new执行构造函数Fn时,创造了一个实例对象f,实例对象f的__proto__指向构造函数Fn的原型prototype。
  (3)因为实例对象f的__proto__指向构造函数Fn的原型prototype,所以实例对象f可以间接访问到Fn原型prototype的方法。
                                       
4、查看实例对象f是否有指针指向构造函数Fn的原型:
  (1)isPrototypeOf()用于检测两个对象之间似乎否存在这种关系,使用方法如下:
    Fn.prototype.isPrototypeOf(f)    // 查看 Fn 的 prototype 对象,是否是 f 原型
  (2)类似的还有instanceof运算符,使用方法如下:
    console.log(f instanceof Fn)     // 查看 f 对象是否是构造函数 Fn 的实例
    console.log(f instanceof Object)
    tip:两种使用,如果是返回ture,如果不是返回false。
    tip:instanceof运算符右侧为构造函数,并且js中所有原型都来自Object构造函数。
5、javascript中解析器访问属性顺序:
  (1)当访问实例 f 的属性或方法时,会先在当前实例对象 f 中查找,如果没有,则沿着__proto__继续向上寻找,如果找到最顶头的Object还是找不到,则会抛出undefined。如果在实例中找到,或某层原型中找到,就会读取当前值并执行,同时停止向上找寻。
  (2)由此可见,解析器的解析顺序遵循就近原则,如果在最近的位置发现属性存在,便不会继续向上找寻。
 
 
 
 
 
 
 
 
 
 
 
 
 
 

JavaScript中闭包的使用和各种继承介绍的更多相关文章

  1. 在Javascript中闭包(Closure)

    在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...

  2. javascript中闭包最简单的简绍

    javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量.私有变量可以用到闭包.闭包就是将函数内部和函数外部连接起来的一座桥梁. 函数的闭包使用场景:比如我们想要一个函数来 ...

  3. 在JavaScript中闭包的作用和简单的用法

    在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...

  4. JavaScript中闭包之浅析解读

    JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常 ...

  5. 关于javascript中闭包的理解

    闭包就是能够读取其他函数内部变量的函数. 在javascript中,只有函数内部的子函数可以读取局部变量,因此,我理解闭包就是定义在一个函数内部的函数. 例子: var f1 = function() ...

  6. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

  7. javascript中闭包的概念

    这个是每个前端工程师绕不开的一个问题,网上各种资料很多,整个春节,我仔细研读了红皮经典中关于这一块的注释,加深了对这一块的理解. 有好几个概念需要重申一下.以下都是我的理解: 1. 闭包是javasc ...

  8. Javascript中闭包的作用域链

    作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域. 闭包一般发生在嵌套作用域中.闭包是JavaScript最强大的特性之 ...

  9. JavaScript中闭包实现的私有属性的getter()和setter()方法

    注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...

随机推荐

  1. Django学习笔记(一):第一个django程序

    1.创建和运行 django-admin startproject xxx python manage.py runserver 2.第一个项目程序 wsgi.py中文名:python服务器网关接口. ...

  2. hive正则表达式的用法

    regexp_replace用法 1.  截取字符串中的汉字部分: 举个栗子:select regexp_replace('七夕节comming!来啦','([^\\u4E00-\\u9FA5]+)' ...

  3. 019 模块2-time库的使用

    目录 一.概述 二.time库基本介绍 2.1 time库概述 三.时间获取 四.时间格式化 4.1 格式化控制符 4.2 时间格式化-代码 五.程序计时应用 5.1 程序计时 六.单元小结 参考:h ...

  4. NOIP2012 D2 T3 疫情控制 洛谷P1084

    题目链接:https://www.luogu.org/problemnew/show/P1084 算法:倍增,二分答案,贪心 + 瞎搞.. 背景:上学长的数论课啥也听不懂,于是前去提高组找安慰.不巧碰 ...

  5. asp.net core webapi 统一处理返回值、异常和请求参数验证

    现在的开发模式很少用asp.net mvc一个项目直接操作界面和数据库了.大部分都使用前后端分离,更多的是为了让API支持移动端. 后端写webapi的时候必然需要和前端约定请求值和返回值的格式,如果 ...

  6. Spring SpringMVC myBatis(简称SSM)理解

    1对Spring的理解 (1)spring是什么? spring是Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架. (2)spring的作用 (a)spring ...

  7. 上传本地Jar包到阿里云的云效私有仓库

    一.前言 前2天玩了一下上传本地jar到maven中央仓库,随后我们老大又给我说了一个叫云效的私有仓库也可以玩,小编试了一下,果然很舒服,配置很简单,效率很高,几分钟就能搞定,只需要自己有个阿里云的账 ...

  8. lvm创建逻辑卷技巧

    公司使用的服务器都是虚拟机,是虚拟机管理员通过模板创建的. 创建的所有逻辑卷都是使用的sda盘. 而我们在部署应用时需要和系统所在盘分离.(提高磁盘读写速度,避免系统盘被占满) 以前都是先创建新的逻辑 ...

  9. 自定义构建基于.net core 的基础镜像

    先说一个问题 首先记录一个问题,今天在用 Jenkins 构建项目的时候突然出现包源的错误: /usr/share/dotnet/sdk/2.2.104/NuGet.targets(114,5): e ...

  10. java通过代理创建Conncection对象与自定义JDBC连接池

    最近学习了一下代理发现,代理其实一个蛮有用的,主要是用在动态的实现接口中的某一个方法而不去继承这个接口所用的一种技巧,首先是自定义的一个连接池 代码如下 import java.lang.reflec ...