• 做预解释题的一点小方法和小技巧


    
    

        在JavaScript中的函数理解中预解释是一个比较难懂的话题。原理虽然简单,寥寥数言,但其内涵却有深意,精髓难懂。如何在轻松活跃的头脑中将它学会,现在针对我在学习中的一点小窍门给大家分享一下,希望能给大家一些帮助:

    
    

    万事需遵循“原理”——“预解释”无节操和“this”指向:(可先看例题解析然后结合原理进行学习)

    (感谢蕾蕾老师给归纳的预解释无节操原理:)

    
    

    如果函数传参数则先于以下执行,就相当于在函数私有作用域下var了一个变量;根据作用域原理,私有作用域的权重永远大于父级作用域,当我私有作用域中有某个变量时,而我正好需要他时,私有作用域变量的值就是我所需要的;当私有作用域中没有时,而我有恰好需要它时,我就会沿着作用域链一级级的往上找。此时可得出子级可以用父级的变量,但父级不能访问子级的作用域,打个简单的比喻可能不太贴切,子孙能继承祖宗的财产,但祖宗不能继承子孙的财产,因为祖宗都没了,还怎么继承。

    
    

    1. 只对等号左边带var的,声明但不定义
    2. 自执行函数不会进行预解释,只有,执行到他的时候,声明+定义+调用同步完成
    3. 已经声明过的不会进行重复声明,但会重新赋值;
    4. return下面的语句虽然不会执行,但会进行预解释;
    5. 函数的声明早于变量的声明
    6. 在条件判断语句中,无论条件是否成立,都会进行预解释;
         不要在条件判断语句中写函数的定义阶段;否则,各大浏览器对其的兼容性不同
    this指向:

    
    

    1. 当一个元素身上的事件被触发的时候,会执行一个函数,函数中的this指向当前这个元素;
    2. 自执行函数中的this,永远都是window
    3. 回调函数中的this,一般都是windowsetInterval(函数名,1000)  ary.sort(function(){})
    4. 当函数被调用的时候,看前面是否有".""."前面是谁,this就是谁;

    原理阐述篇————实例小窍门篇:
    1

    1 (function f(){
    2     function f(){ return 1; }
    3     alert (f());
    4     function f(){ return 2; }
    5 })();


    解析:此函数为自执行函数,观察函数,注意类似于function fn(){}这样的才是声明函数,像var f=function(){}b=function(){}这样的都不属于声明函数,前者属于变量的声明,

    
    

    只有像声明函数那样的在函数才会进行预解释,此题中两个为需要声明的函数为同名函数,所以根据已经声明过的不会进行重复声明,但会重新赋值原理得到函数预解释为 function f(){ return 2; }
    此时,当函数执行时

    
    

    alert (f())的结果为2
    2

    
    
    var a=12;
    function show(){
        alert(a);
        a=15;
    }
    show();
    alert(a);



    解析:此题为对作用域链的考察,先进行预解释,特别提示变量只有声明,函数既有声明还有定义,预解释了之后代码执行时就会自动跳过不执行,但var a=12,这相当于给变量重新赋值,因为任何变量进行预解释的初始值为

    undefined;本题先对变量和函数进行预解释:var a=undefined;

    function show(){
        alert(a);
        a=15;
    }                     
     预解释完毕后,代码从上往下的执行,1. a=12; 2. function show(){alert(a);a=15}已经经过预解释不会执行; 3. show()进行函数的调用,alerta.当前作用域下没
    a,就去父级作用域,a=124.接着执行a=15,任何在函数私有作用域下'变量'前面不带var的本身不属于当前作用域域,而是对全局作用域中全局变量的重新赋值,所
    以此时相当于把全局变量中的a直接赋值为15; 5.最后在全局作用域下alert(a),只能访问自己的变量。所以a=15;

    此题答案为 12,15

    此题引申:

    
    
    1 var a=12;
    2 function show(){
    3     alert(a);
    4    var a=15;
    5 }
    6 show();
    7 alert(a);



    此时输出的结果为undefined12,你猜对了吗?切记私有作用域中的变量是以var为基准的,当然如果传参数例外,因为传参就相当于最先var,此题在show函数执行时,因为

    
    

    里面有var,所以肯定有私有变量所以var a,接着alerta),大家应该没有忘记任何变量的预解释初始值为undefined,接着执行var a=15,此时相当于重新赋值,这里不用有疑问,因为代码
    是从上往下执行,接着继续执行外面全局变量中的alerta)此时值为12,因为函数私有作用域中并没有改变全局变量的值。

    再引申:

    
    
    1 var a=12;
    2 function show(a){
    3     alert(a);
    4    var a=15;
    5 }
    6 show(a);
    7 alert(a);


    此题结果应为12,12,此题相对于上一题做的改善是对函数进行了传参数处理,上面提过传参相当于最先进行var变量处理,所以在show函数执行时,私有变量a的最开始赋值就为12,在执行就相当于重新赋值

    事已至此,咱们再引申一下:

    
    
    1 var a=12;
    2 function show(a){
    3     alert(a);
    4     a=15;
    5 }
    6 show(a);
    7 alert(a);


    此题结果应该为:12,15,此题主要关键点为全局变量的从新赋值:

    那么大家肯定就更能做出这道题了:

    
    
    1 alert(a);
    2 var a = 12;
    3 function show(a) {
    4     alert(a);
    5     var a = 15;
    6     alert(a);
    7 }
    8 show(a);
    9 alert(a);
    
    

    此题结果为undefined1215,12

    2:接下来我们来讨论一下变量和函数的一些关系:

    
    
    1 function a() {
    2     var b=10;
    3     alert(b);
    4 };
    5 var a;
    6 a();


    解析:此题中变量和函数为同名,根据原理知识我们可以知道,函数的声明要优先于变量的声明,所以当同名时以函数优先,所以不难的出此题的答案为10;别急,你以为这么简单就完了,来开始做个小修改
    引申一下:

    
    
    1 function a() {
    2     var b=10;
    3     alert(b);
    4 };
    5 var a=6;
    6 a();


    解析:大家猜猜这道题的结果,如果你对上面的原理理解的不错的话,那么你应该很容易得出此题会报错,a is not defined; 确实函数占用了名称,当接下来执行var a=6,时,大家要注意了,只要变量
    有等号就相当于重新赋值,但大家疑问来了,为啥会报错呢,请注意a的名字已经被函数占用,当你进行var a=6,时此时你又把a赋值给6,此时函数本身就犹如孤魂野鬼,没有名字,当最后调用啊a()我去哪找函数a,所以必须的必肯定会报错!!!
    3

    1 if("a" in window){
    2     var a=15;
    3 }
    4 function fn() {
    5     alert(a)
    6 }
    7 fn()

    解析:此题考查的知识点为在条件判断语句中,无论条件是否成立,都会进行预解释,在此题中,大家也应该记住类似于“a” in window 都是正确的,所以起先会进行预解释 var a, 因为条件成立,进入
    条件语句中会进行重新赋值,此时a=15;在函数中alerta,向上级作用域寻找a,结果为15

    引申:

    
    
    1 if(!"a" in window){
    2     var a=15;
    3 }
    4 function fn() {
    5     alert(a)
    6 }
    7 fn()


    解析:加个,条件肯定为false,不进入条件,但会进行预解释var a,此时a 的值为undefined

    接下来将他们综合起来先来个简单的综合:

     

    1 var name='haha';
    2 var age=500;
    3 name=(function(name,age){
    4     arguments[0]='xixi';
    5     age=age||this.age;
    6     console.log(name,age);
    7 })(name);
    8 console.log(name,age)

     

     

    解析:看到此题,来吧先进行预解释,1.var name;var age;此时有个注意点,name=...;等号后面的函数不会进行预解释。2.代码从上到下执行,name='haha';age=500;3.接下来是个关键点name等于一个自执行函数,先看看它有没有返回值,一个函数执行后若没有返回值则结果都等于undefined,所以此时全局name=undefined,此时自执行函数执行时,函数经过传参,就相当于提前var,所以有私有变量,arguments[0]='xixi';此时就相当于将函数私有作用域中name=xixi;age=age||this.age,自执行函数的this指向为window,"||"为或的意思,有一项成立就行,那么age=500.第一次console结果应该为xixi,500  4.全局的console我们刚才分析了name富裕没有返回值的自执行函数时为undefined,所以结果为undefined,500;



    今天先更新点简单的,明天加上内存释放等问题,通过特殊的小技巧让你事半功倍,做爽预解释,不用画图也能看出答案。。。

    未完,待续....

    
    
    
     
  • 相关阅读:
    【leetcode-100】 简单 树相关题目
    【leetcode-101】 对称二叉树
    【2】【leetcode-105,106】 从前序与中序遍历序列构造二叉树,从中序与后序遍历序列构造二叉树
    【leetcode-102,107,103】 二叉树的层次遍历
    iOS开发
    对称加密和不对称加密原理
    uiimageview 异步加载图片
    如何让IOS中的文本实现3D效果
    SDWebImage使用,图片加载和缓存
    ios 图片处理( 1.按比例缩放 2.指定宽度按比例缩放
  • 原文地址:https://www.cnblogs.com/peakol/p/7067679.html
Copyright © 2020-2023  润新知