理解javascript的闭包,原型,和匿名函数及IIFE
理解javascript的闭包,原型,和匿名函数(自己总结)
一 .>关于闭包
理解闭包 需要的知识
1.变量的作用域
- 例1:
- var n =99; //建立函数外的全局变量
- function readA(){
- alert(n); //读取全局变量
- }
- readA(); //执行此函数
- 例2:
- function readB(){
- var c = 9;
- function readC(){
- console.log(c); //ok c可见
- }
- return readC;
- }
- alert(c); //error c is not defined.
note: 函数内部声明变量c时,一定要加上 var,否则 c会成为一个全局变量
所以函数内可见全局变量,函数内的局部变量却对外不可见
js的作用域是链式的,父对象里的变量总对子对象可见,子对象的对象却对父对象不可见
当我们要获取函数内的内部变量
于是有了例3:
- function readB(){
- var c = 9;
- function readC(){
- console.log(c);
- }
- return readC();
- }
- readB();
闭包很类似基于此做了一个变式
- function readB(){
- var c = 9;
- function readC(){
- console.log(c);
- }
- return readC;
- }
- var res = readB();
- res();
note:
1.慎用闭包,注意内存占用,因为它会保存父函数的状态
2.不要随便改变父函数内部变量的值
理解闭包
note: this 指包含它的函数被执行时所属的对象
- 例1:
- var name = "The Window";
- var object = {
- name : "My Object",
- getNameFunc : function(){ //此时this (这个执行函数)是属于object对象的,是object对象下的一个属性的值
- return function(){ //此时this (这个执行函数)是一个匿名函数,从根对象window生成,是属于window
- return this.name;
- };
- }
- };
- console.log(object.getNameFunc()()); //the window
- 例2:
- var name = "The Window";
- var object = {
- name : "My Object",
- getNameFunc : function(){
- var that = this;
- return function(){
- return that.name;
- };
- }
- };
- console.log(object.getNameFunc()()); //My Object
二 .>匿名函数 IIFE
直接定义一个匿名函数 然后调用这个匿名函数,这种形式在jquery插件的定义时很常见
1.通过函数字母量的方式. 先声明一个匿名函数,然后执行它
- ( function(){
- console.log('excute self');
- }) ();
2.通过优先表达式的方式 , 由于Javascript执行表达式是从圆括号里面到外面,所以可以用圆括号强制执行声明的函数
- (
- function () {
- alert(2);
- }
- ()
- );
3.void操作符 用void操作符去执行一个没有用圆括号包围的一个单独操作数
- void function(){ console.log('void') } ();
- 在Bootstrap源码(具体请看《Bootstrap源码解析》)和其他jQuery插件经常看到如下的写法:
- Js代码
- +function ($) {
- }(window.jQuery);
- 这种写法称为:
- IIFE (Imdiately Invoked Function Expression 立即执行的函数表达式)
- 一步步来分析这种代码:
- 先弄清 函数表达式(function expression)和 函数声明(function declaration)的区别:
- 函数表达式 Function Expression - var test = function() {};
- 函数申明 Function Declaration - function test() {};
- 函数表达式中的函数可以为匿名函数,也可以有函数名,但是该函数实际上不能直接使用,只能通过表达式左边的变量 a 来调用
- var a = function(){
- alert('Function expression');
- }
- var b = new a();
- 函数声明时必须有函数名
- function a(){
- alert('Function declaration');
- }
- a();
- 这是一个匿名函数
- function () {
- }
- 你也许注意到匿名函数在console下会报错。console的执行和报错如下:
- function(){}
- SyntaxError: Unexpected token (
- 通过一元操作符+变成了函数表达式。
- 也可以使用 - ~ !等其他一元运算符或者括号,目的是为了引导解析器,指明运算符附近是一个表达式。以下是三种经典方式 :
- +function () {
- };
- (function () {
- });
- void function() {
- };
- 函数表达式通过 末尾的() 来调用并运行。就是一个IIFE
- +function () {
- }();
- (funtion () {
- })();
参考:http://suqing.iteye.com/blog/1981591/
三 .>关于prototype
原型 prototype
理解js中的protitype首先需要明白js的面向对象设计
- function People(name){
- this.name = name;
- console.log(this); //Window 或者 object { name: 'xxx' }
- this.introduce = function(){ //实例对象方法
- console.log(this.name);
- }
- }
- new People('leon').introduce();
- //这里有一个非常有趣的现象,结合前面的来看的话,
- //首先function people里的this指向的默认是Window对象
- //当 调用 People();时 this 输出为 Window对象
- //但一旦调用new People('xx')时, this 输出为 {name:'xx'}
- //其实也很好理解,一旦new ,便新建了一个对象
实例对象方法只能这样 new People('leon').introduce(); 调用 因为它使用前必须初始化
类的对象的静态方法
- var People = {}; //等于一个对象 {} 或者 function 数组都可以 此时People需要是引用类型
- People.sayhi = function(to_who){
- console.log('hi '+ to_who);
- }
- People.sayhi('lee'); //调用时这样调用
原型方法
- var People = function(){}; // People 必须为一个 function(){} 即为一个类,不能是对象或值类型或其他引用类型
- People.prototype.meet = function(meet_who) {
- console.log('I am '+this.name + ',going to meet ' + meet_who);
- };
- new People('lee').meet('xx');
原型方法只能由该类的对象 调用
A.prototype = new B();
原型看起来很像继承,但其实不是,它更像clone更准确
如果出现了父类和子类出现了重名的属性,采取就近原则,如果找不到一级一级向上找,如果要指定调用上级的属性,使用call方法
- function baseClass()
- {
- this.showMsg = function()
- {
- alert("baseClass::showMsg");
- }
- }
- function extendClass()
- {
- }
- extendClass.prototype = new baseClass();
- var instance = new extendClass();
- instance.showMsg(); // 显示baseClass::showMsg
extendClass.prototype = new baseClass();
var instance = new extendClass();
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);
obj1.func.call(obj);
理解javascript的闭包,原型,和匿名函数及IIFE的更多相关文章
- Javascript闭包和C#匿名函数对比分析
C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...
- 深入理解JavaScript的闭包特性如何给循环中的对象添加事件
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- 深入理解javascript的闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- 理解Javascript 的闭包(closure)
要理解闭包的概念先从变量的作用域说去 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之 ...
- 如何给循环中的对象添加事件--深入理解JavaScript的闭包特性
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- 深入理解JavaScript的闭包特性 如何给循环中的对象添加事件(转载)
原文参考:http://blog.csdn.net/gaoshanwudi/article/details/7355794 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数 ...
- 闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别
闭包(Closure)和匿名函数(Anonymous function)/lambda表达式的区别 函数最常见的形式是具名函数(named function): function foo(){ con ...
- js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题)
js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题) 一.总结 需要好好看下面代码 本质是因为匿名函数用到了循环中的变量,而普通方式访问的话,匿名函数的访问在循环之后,所以得到的i是循环 ...
- 深入理解JavaScript系列(15):函数(Functions)
介绍 本章节我们要着重介绍的是一个非常常见的ECMAScript对象——函数(function),我们将详细讲解一下各种类型的函数是如何影响上下文的变量对象以及每个函数的作用域链都包含什么,以及回答诸 ...
随机推荐
- Centos7安装Mysql5.7并修改初始密码
1.CentOS 的yum源中没有mysql,需要到mysql的官网下载yum repo配置文件. wget https://dev.mysql.com/get/mysql57-community-r ...
- P1875 佳佳的魔法药水
P1875 佳佳的魔法药水 题目描述 发完了 k 张照片,佳佳却得到了一个坏消息:他的 MM 得病了!佳佳和大家一样焦急 万分!治好 MM 的病只有一种办法,那就是传说中的 0 号药水 ……怎么样才能 ...
- 6.bootstrap 将文本内容关联一个动作(手机端导航适配)&在超小尺寸下显示,屏幕变大后消失
1.情景:这是出现在手机端导航适配的,点击文本MENU可以出现下拉的list 解决方法: 1.首先要想到,MENU只有两个状态,因此可以用checkbox实现 2.将MENU放在label标签里面,l ...
- 《Cracking the Coding Interview》——第11章:排序和搜索——题目8
2014-03-21 22:23 题目:假设你一开始有一个空数组,你在读入一些整数并将其插入到数组中,保证插入之后数组一直按升序排列.在读入的过程中,你还可以进行一种操作:查询某个值val是否存在于数 ...
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目3
2014-04-23 18:10 题目:设计一个点唱机. 解法:英文叫Musical Jukebox.这是点唱机么?卡拉OK么?这种题目实在是云里雾里,又没有交流的余地,我索性用一个vector来表示 ...
- Delphi中的关键字与保留字
Delphi中的关键字与保留字 分类整理 Delphi 中的“关键字”和“保留字”,方便查询 感谢原作者的收集整理! 关键字和保留字的区别在于,关键字不推荐作标示符(编译器已经内置相关函数或者留给保留 ...
- 【Matrix Factorization】林轩田机器学习技法
在NNet这个系列中讲了Matrix Factorization感觉上怪怪的,但是听完第一小节课程就明白了. 林首先介绍了机器学习里面比较困难的一种问题:categorical features 这种 ...
- 一个初学者的辛酸路程-前端js
内容回顾: 1.CSS的基本概念: 层叠样式表. 2.CSS的三种书写方式 ① 行内样式 <div style="color: red;">sdfdsf</div ...
- (笔记) RealTimeRender[实时渲染] C2
@author: 白袍小道 @来源:RealTime Render @建议书籍:龙书.RealTimeR第四版.GPUGem和PRO (来源:暗影不解释) 引点 这一章关注的管线中的管道功能,而非实现 ...
- sdram之乒乓操作
在实时显示时,为了保证画面显示的完整性需要对SDRAM进行乒乓操作. SDRAM 中有 4 个bank ,地址分别为00 01 10 11,后面将用 0 1 2 3来描述 bank 0和1 作为第一个 ...