闭包

一、基本概念
闭包:闭包是指有权访问另一个函数作用域中的变量的函数。
创建方式:创建闭包的常见方式,就是在一个函数内部创建另一个函数。

二、相关概念
执行环境:执行环境(也称为环境)是JS中一个最为重要的一个概念。执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为。全局执行环境是最外围的一个执行环境。
作用域链:作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问,作用域链的前端始终都是当前执行的代码所在环境的变量对象。
标识符解析:标识符解析是沿着作用域链一级一级搜索标识符的过程,搜索过程始终从作用域链前端开始,逐级向后搜索,直到找到标识符为止,如果没找到那就是undefined了。

三、闭包的使用

有编号为1-100的100个按钮,实现点击每一个按钮弹出其对应的序号的交互效果


var buttons = document.querySelectorAll('button')
for(var i = 0; i < buttons.length; i++){buttons[i].onclick = function(){alert(i+1)}
}

代码分析:变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,所以所有的按钮点击事件引用的都是同一个变量 i 。当整个for循环执行完毕后,变量i的值变为100,所以弹出的都是101这个数。但是,我们可以通过创建另一个匿名函数强制让闭包的行为符合预期。


var buttons = document.querySelectorAll('button')
for(var i = 0; i <buttons.length;i++){buttons[i].onclick = (function(num){return (function(){alert(num+1)})})(i)
}

代码分析:定义了一个匿名函数,并将立即执行这个函数之后的结果赋给绑定事件。这里的匿名函数有一个参数 num,在调用每个匿名函数时,我们传入了变量 i。由于函数参数是按值传递的,所以就会将变量 i 的当前值复制给参数 num。而在这个匿名函数内部,又创建并返回了一个访问 num 的闭包。这样一来,每个点击事件的回调函数都有自己num 变量的一个副本,因此就可以返回各自不同的数值了。


var buttons = document.querySelectorAll('button')
for(let i = 0; i < buttons.length; i++){buttons[i].onclick = function(){ alert(i+1)}
}

代码分析:上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后能实现我们想要的效果。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式不再必要了。

JavaScript的设计模式

一、构造函数模式
构造函数用于创建特定类型的对象——不仅声明了使用的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值。
所谓”构造函数”,其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

unction Cat(name,color){this.name=name;this.color=color;// this.eat = function(){alert("吃老鼠");};
}
var cat1 = new Cat("大毛","黄色");
var cat2 = new Cat("二毛","黑色");alert(cat1.name); // 大毛
alert(cat1.color); // 黄色cat1.eat(); // 吃老鼠
cat2.eat(); // 吃老鼠

这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。

     alert(cat1.constructor == Cat); //true

instanceof运算符,验证原型对象与实例对象之间的关系

    alert(cat1 instanceof Cat); //true

对于每一个实例对象,eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率

优点:每个实例的公共对象都是不同的,不会相互影响。

二、原型模式
原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象。
Javascript中没有类的概念,就算ES6中引入的class也不过是一种语法糖,本质上还是利用原型实现。在原型编程语言中,类并不是必需的,对象不一定需要由类实例化而来,而是通过克隆另外一个对象来得到。

原型模式是用来创建对象的一种模式。在以类为中心的语言中,要创建一个对象首先要指定这个对象的类型,然后实例化一个对象。使用原型模式创建对象时不必关心对象的具体类型,而是找到一个对象,然后通过克隆来创建一个一模一样的对象。

function Master(){this.blood = 100;this.level = 6;
}
var noumenon = new Master();
noumenon.level = 9;
var ektype = Object.create(noumenon);
console.log(ektype);

通过以上代码,我们看到了如何通过原型模式来克隆出一个一模一样的的对象。原型模式的真正意义并非创建一个一模一样的对象,而是提供一种创建对象的方式,Javascript的面向对象机制是基于原型模式的,他的对象系统就是使用原型模式,通过克隆来创建的,克隆是创建一个对象的过程和手段。以继承为例:

function Person(name){this.name = name;
}
function Developer(lang){this.language = lang;
}
var p = new Person('coder');
Developer.prototype = p;
var dev = new Developer('Javascript');

基于原型的继承体系,子类的每次实例化都是对其构造函数的prototype属性的克隆。所以每次创建Developer对象,其实都是在对p对象的克隆。

在Java等以类为中心的面向对象语言中,经常使用new实例化一个对象。但是Javascript是基于原型的面向对象语言,在这里new运算符创建对象的方式与Java中的new运算符并不相同,Javascript中的new运算符也是通过克隆来实例化对象的,克隆的是构造器函数的原型对象,new运算符的作用等同于如下代码:

function Person(name){this.name = name;
}
function Developer(lang){this.language = lang;
}
var p = new Person('coder');
Developer.prototype = p;
function _new(_Constructor) {var that = Object.create(_Constructor.prototype);var args = Array.prototype.slice.call(arguments, 1);var other = _Constructor.apply(that, args);return (typeof other === 'object' && other) ? other : that;
}
_new(Developer, 'JavaScript')

从这我们也可以看出,Javascript的原型实际上存在着诸多矛盾,它的某些复杂语法看起来就像那些基于类的语言,这掩盖了它的原型机制。所以jQuery中尽量避免使用new运算符来创建对象。

Prototype模式的验证方法:

function Cat(name,color){this.name = name;this.color = color;
}
Cat.prototype.type = "猫科动物";
Cat.prototype.eat = function(){alert("吃老鼠")};
var cat1 = new Cat("大毛","黄色");
var cat2 = new Cat("二毛","黑色");
alert(cat1.type); // 猫科动物
cat1.eat(); // 吃老鼠
  • isPrototypeOf()

    判断某个proptotype对象和某个实例之间的关系

 alert(Cat.prototype.isPrototypeOf(cat1)); //truealert(Cat.prototype.isPrototypeOf(cat2)); //true
  • hasOwnProperty()

    用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性

alert(cat1.hasOwnProperty("name")); // true
alert(cat1.hasOwnProperty("type")); // false
  • in运算符
    用来遍历某个对象的所有属性
for(var prop in cat1) { alert("cat1["+prop+"]="+cat1[prop]); }

原型模式优点
1. 减少内存消耗,系统资源占用少,所有实例共享同一方法,不会创建多个
2. 原型对象继承时,子类在重写父类原型方法时很方便 ,可以很方便 调父类房法,再扩展。
原型模式缺点
1. 优点1既是最大的优点,也同样带来一个严重问题,如果共享的对象是引用 对象(如array)则也会造成多个实例共享同一个array,很可能会相互影响

2017.12.29会议记录相关推荐

  1. 2017/12/29

    2019独角兽企业重金招聘Python工程师标准>>> 2017/12/29 Firday weather: light rain ! 1.需求: 写一个脚本实现如下功能: 输入一个 ...

  2. 【一周头条盘点】中国软件网(2017.12.25~2017.12.29)

    每一个企业级的人 都置顶了 中国软件网 中国软件网 为你带来最新鲜的行业干货 趋势洞察 麦肯锡:人工智能三个关键业务方向一个最大问题 麦肯锡表示:关于人工智能的三个关键业务方面开始逐渐明朗化. 第一, ...

  3. 抓住窗口期 成就世界级 —— 29周年之际致全体同仁 wwj 2017.12.6

    [企业与公共组织数字化时代,如何做好产品],重点学习老王精神::::: 抓住窗口期  成就世界级 --在用友创立29周年之际致用友全体同仁 WWJ 2017.12.6

  4. 自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索、推荐以及算法相关工作。多年来主要从事推荐系统以及机

    自然语言处理技术(NLP)在推荐系统中的应用 原2017.06.29人工智能头条 作者: 张相於,58集团算法架构师,转转搜索推荐部负责人,负责搜索.推荐以及算法相关工作.多年来主要从事推荐系统以及机 ...

  5. 2010.12.29(2)——— android GridView

    2010.12.29(2)--- android 可伸缩的GridView 用 GridView 来实现九宫格布局 并且一个格显示一个图片和一行字 [b]1.ImageAdapter[/b] pack ...

  6. poi 公式转 图片_三阶魔方公式符号图解V2.0(2017/12/15)_碧海风云

    本文出自微信公众号[碧海风云]之<三阶魔方公式符号图解V2.0(2017/12/15)_碧海风云> 公式符号概述 英国原伦敦南岸大学数学教授大卫·辛马斯特(David Breyer Sin ...

  7. 2017.12.20 静态网页小实战

    时间:2017.12.20 地点:武汉-学校 项目类型:静态网页-王者荣耀游戏相关网页 制作时间:差不多半个月 主页面html代码: <!doctype html> <html> ...

  8. 死性不改【17Fi】ISO9000 Win7x64专业版、WS2008r2企业版GHO下载 2017.06.29

    死性不改[17Fi]ISO9000 Win7x64专业版.WS2008r2企业版GHO下载 2017.06.29 2017年06月29日 系统分享 评论 2 条 阅读 2,341 次 最新版本:17F ...

  9. 2019.12.29 BMR计算

    这个 示例是进行BMR计算,主要是获取用户的输入数据,对获取的数据进行分隔,然后进行字符转换进行求解 本示例涉及知识点: ①整数.浮点数.数值运算 ②if-else语句.while语句.input语句 ...

最新文章

  1. php7 出现Class 'DOMDocument' not found的解决方法
  2. RedisTemplate实现事物问题剖析和解决
  3. 如何独立实现一个基于知识图谱的问答系统
  4. 浅析Windows7的睡眠、休眠、混合睡眠、离开模式
  5. 顺序一致性内存模型与JMM的“顺序一致性”
  6. 项目管理工具project软件学习(六) - 设置里程碑、任务备注
  7. SQLServer 2000中,存储过程和用户自定义函数具体的区别??
  8. 字节流 system.out ----printStream
  9. 联想自带Y空间软件最好用的版本-可录屏无其它提示
  10. 原生WebView长截图 和 Tencent x5webview截长图
  11. 成都以前的计算机学校图片,成都计算机中职图片介绍
  12. ST-Link驱动安装包 STM32 keil
  13. 产品读书《自控力:斯坦福大学最受欢迎的心理学课程》
  14. windows server2012安全配置—停用Guest帐号的方法
  15. 工作三年的Java程序员应该达到什么水平?
  16. XML技术在电子病历中的应用
  17. 两种 iPhone 界面的动画效果
  18. 程序员经验分享:34岁安卓开发大叔感慨,好文推荐
  19. 国内android6.0,更流畅体验佳 可升级安卓6.0机型盘点
  20. 计算机辅助外科手术系统,计算机辅助外科手术.pdf

热门文章

  1. To B市场运营难?10位大咖总结出的精准获客之道
  2. 万字长文详解特斯拉自动驾驶体系(感知/规控/标注/仿真)
  3. 乐讯网python论坛_乐讯机器人(论坛社区刷发帖刷回复)V20140714 高级版
  4. 共享文件夹/盘加密方法:(指定电脑或者拥有用户名和密码才能访问)
  5. 【天命奇御】成就进度62/71的通关攻略(6·传闻篇)
  6. 菜鸟学习OGRE和天龙八部之十八: 获得档案(Archive)文件列表
  7. vscode关闭源代码管理处的提示
  8. Ceph文件存储-挂载文件系统
  9. 总结HTTP中常见的一些名词
  10. 【流畅的 C】流畅使用 C 语言