bom 和this指向与闭包

一、JavaScript 闭包

    闭包概述

        基本描述:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

        相关理论:

            (1)JavaScript语言允许使用内部函数,即允许在一个函数内部进行另外一个函数的声明。

[javascript]  view plain  copy
  1.     function func1 () {  
  2.         function func2 () {}  
  3.     }  

            (2)JavaScript语言允许存在链式作用域(chain scope),即在一个函数内部声明另外一个函数,内层函数可以直接访问外层函数中声明的所有局部变量、参数和声明的其他内部函数。

[javascript]  view plain  copy
  1.     function func1 () {  
  2.         var temp = 1;  
  3.         function func2 () {  
  4.             console.log(temp);  
  5.         }  
  6.     }  

        相关语法:

            因为闭包并没有绝对统一的语法,因此我们采用较为简单的形式来对闭包进行展示,为避免引起歧义,在此郑重声明:闭包绝对不等于匿名函数,闭包是一种代码编译器技巧,其作用是能够使得内部函数能够访问上级函数的内容。


    闭包实例

        在JavaScript世界中,函数外部无法【直接访问】函数内部的局部变量,这是不容否定的。但凡是总有例外,在实际开发过程中总是有这样或者那样的原因,使得开发者不得不在函数外部对函数内部的局部变量进行操作。这就需要用到闭包的技巧。

        在上面的代码中,可以明确看到,在func2内部由于chain scope的存在,可以对局部变量temp进行直接访问,还记得之前提到过的一个名为【一等公民】的概念,两者结合,闭包结构便新鲜出炉。

[javascript]  view plain  copy
  1.     function func1 () {  
  2.         var temp = 1;  
  3.         return function () {  
  4.             console.log(temp);  
  5.         };  
  6.     }  

    闭包作用

        基本描述:闭包的作用在实际开发中不可估量,其作用也并不是三言两语就能够完全交代清楚。其很多价值的体现都必须结合实际开发中的某种具体情况才能说明,但无论如何,其作用主要体现在以下两个方面上:

        (1)闭包结构,允许函数外部对函数内部的局部变量、形式参数进行直接读取。

        (2)闭包结构,能够使得局部变量所占内存始终不被回收。

[javascript]  view plain  copy
  1.       
  2.     function func1 () {  
  3.         var temp = 1;  
  4.         return function () {  
  5.             temp ++;  
  6.             console.log(temp);  
  7.         };  
  8.     }  
  9.     var tempFunc = func1();  
  10.     tempFunc();  // 2  
  11.     tempFunc();  // 3  

二、JavaScript 匿名函数

    匿名函数

        相关说明:实际上在JavaScript世界中并没有必要单独将【匿名函数】提炼出来作为单一的知识点来说。因为匿名函数根本算不得是具有某种特征的函数分类,而最多只能算是函数写法中的一种而已。

        基本描述:在声明的过程中没有显式的写出函数名的时候,将其统称为匿名函数。

        语法结构:function () {}

        注意事项:

            (1)单独书写匿名函数本身并无任何实际意义,通常匿名函数都会配合其他的写法来达到不同的目的。

[javascript]  view plain  copy
  1.         1  var func1 = function () {}; //   
  2.         2  return function () {};  
  3.         3  (function () {})();  

            (2)建议:匿名函数只是一个习惯上的叫法,并不用过多的放在心上。与闭包相比,匿名函数可以认为是一个可有可无的称为,可以当作是为了和别人沟通而学习到的一个新的专业名词。


三、JavaScript 自执行函数

    自执行函数

        基本描述:自执行函数,全称为立即自动执行的函数结构表达式(immediately-invoked-function-express),简称IIFE。

        语法结构:(function (形参) {} )(实参);  /  (function (形参) {} (实参));

        存在目的:

            (1)自执行函数不必主动调用,在声明的时候就能立即执行,有利于某些常见的信号量绑定操作。

            (2)分割命名空间,避免对全局变量的命名污染。


        注:闭包closure ≠  匿名函数  ≠  自执行函数IIFE


四、JavaScript 关键字this

    关键字this

        基本描述:this是JavaScript中提出的,一个用来表示其真正调用者的关键字,一般习惯在函数中使用,用来表示函数的真正调用者。

        注意事项:this关键字所代表的内容是动态存在的,根据使用的位置不同将会表现为不同的值。也正因为上述原因,this是无法被确定描述为对象、属性或函数的。

        表现形式:

            (1)this在正常函数中:// 指向函数的调用者

            (2)this在闭包中: // 指向window

            (3)this在间隔调用和延迟调用函数中: // 指向window

            (4)this在自执行函数中: // 指向window

            (5)this在事件监听中:

                        在HTML级事件监听:指向window

                        在DOM0级事件监听:指向函数的调用者(监听绑定的节点)

                        在DOM2级事件监听:(IE)指向window  (非IE) 指向函数的调用者(监听绑定的节点)


五、JavaScript 变更this指向

    变更this指向:概述

        相关说明:如果说this是用来表示【其真正调用者】的一个引用,由系统自动指定this所引用的内容的话,对this关键字的操作方法就必然存在,因为实际开发中this并不如我们想的那么好用。

        相关方法:

            (1)函数执行结果 = 调用函数.call(函数内this的值, 调用函数可能参数1,调用函数可能参数2,...);

            (2)函数执行结果 = 调用函数.apply(函数内this的值,[调用函数可能参数1, 调用函数可能参数2,...]);

            (3)新的函数 = 调用函数.bind(函数内的this值,调用函数可能参数1, 调用函数可能参数2,...);

        注意事项:

            (1)call和apply方法,会在改变函数内this指向的同时直接执行函数,而bind方法则会将变更后的函数以一个新函数的结果返回。

            (2)call、apply还有bind方法的第一个参数是必要参数,如果写null则代表window对象。

        总结:

            call、apply和bind这三个函数的第一个参数都代表了函数调用时this指向的对象,差别主要体现在后面的参数上。call的参数是直接放进去的,第二第三第n个参数全都用逗号分隔,直接放到后面;apply的所有参数都必须放在一个数组里面传进去;bind除了返回的是函数以外,它的语法和call一样。三者的参数不限定是String类型,允许是其他各种数据类型。

    变更this指向:扩展

        事实上变更this指向的方法绝不仅仅只有上面的一种基本用法。下面简单介绍其中两种有关它们的扩展技巧。

        (1)对系统提供的类进行方法的扩展

            描述:通俗来讲,就是让没有某个方法的对象去调用这个“它本不拥有”的方法。

            例子:让arguments集合对象调用数组的slice方法,进而将其本身由【类数组】转变为【真正的数组】

[javascript]  view plain  copy
  1.     function fun () {  
  2.         var arrSlice = Array.prototype.slice;  
  3.         var mySlice = Function.prototype.call.bind(arrSlice);  
  4.         return mySlice(arguments);  
  5.     }  
  6.     console.log(fun(1,2,3,4)); // [1,2,3,4]  

        (2)挑选数组中最大值

[javascript]  view plain  copy
  1.     Math.max.apply(null, [2,3,4,1,6,2,9]); // 9  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值