JS高级(作业域链,闭包,面向对象)

JS高级(作业域链,闭包,面向对象)

作用域链

定义

  • 变量在当前环境now、内部环境f1、内部深层环境f2/f3....都起作用的现象形成了一个链条,这个链条就称为变量的"作用域链"
<script type="text/javascript">
    var title="链条“;
    console.log("now"+title);
    function f1(){
        console.log("f1"+title);
        function f2(){
            console.log("f2"+title);
            function f3(){
                console.log("f3"+title);
            }
            f3();
        }
        f2();
    }
    f1();
</script>

作用域链的作用

  • 变量必须“先声明、后使用”

函数可以“先使用、后声明”,原因是函数有“预加载”过程(函数声明先于其他执行代码进入内存)。本质还是函数的声明在前,使用在后。

<script type="text/javascript">
    f1();
    function f1(){
        console.log("f1"+title);
    }
</script>
  • 内部环境可以访问外部环境的变量,反之不然
  • 变量的作用域是声明时决定的,而不是运行时

闭包

什么是闭包

  • 闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包 形成闭包条件是内部函数需要通过return给返回出来.
<script type="text/javascript">
    function f1(){
        var name="tom";
        var age=18;
        function f2(){
            console.log("名字:"+name+",年龄:"+age);
        }
        return f2;
    }
    var ff=f1();//这就是一个闭包,ff与f2共同指向一个function
    ff();//名字:tom,年龄:age
</script>
  • 解释

f1()调用完成后,垃圾回收器会回收name和age,但是因为ff又去指向function,这样function内部的age和name仍然存在,并且与外部变量无关

闭包使用规则

  • 同一个闭包机制可以创建多个闭包函数出来,它们彼此没有联系,都是独立的。 并且每个闭包可以保存自己个性化的信息。
<script type="text/javascript">
    function f1(){
        var name="tom";
        var age=18;
        function f2(){
            console.log("名字:"+name+",年龄:"+age);
        }
        return f2;
    }
    var ff1=f1();
    var ff2=f2()
    var ff3=f3();
</script>

闭包案例

  • 闭包生成数组元素
<script type="text/javascript">
        var arr=new Array();
       for(var i=0;i<4;i++){
           arr[i]=function () {
               console.log(i);
               return i;
           }
       }
        arr[2]();  //4
        arr[1]();  //4
        arr[0]();  //4
        arr[3]();  //4
    </script>
  • 使用闭包
<script type="text/javascript">
        var arr=new Array();
       for(var i=0;i<4;i++){
           arr[i]=f1(i);
       }
       function f1(n) {
           function f2() {
               console.log(n)
           }
           return f2;
       }
        arr[0]();  //0
        arr[1]();  //1
        arr[2]();  //2
        arr[3]();  //3
    </script>
  • 闭包事件操作
<script type="text/javascript">
      window.onload=function () {
          var cars=document.getElementsByTagName('li');
          //可以利用闭包给每个元素设置独立的函数处理
          //并且函数内部也有独特的下标信息供访问
            for(var i=0;i<3;i++){
                cars[i].onmouseover=over(i);
                cars[i].onmouseout=out(i);
            }
          var col=['red','green','blue'];
          function over(n) {
              function f2() {
                  cars[n].style.backgroundColor=col[n];
              }
              return f2;
          }
          function out(n) {
              function f2() {
                  cars[n].style.backgroundColor="";
              }
              return f2;
          }
      }
    </script>

面向对象操作

① 字面量方式创建

<script type="text/javascript">
        var dog={name:'旺财',age:5,hobby:function () {
            console.log("看家护院")
        }};
        //对已有成员丰富其对象
        dog.color="yellow";
        dog['weight']=80;
        dog.run=function () {
            console.log("在跑步");
        }
        //访问成员
        console.log(dog.name);
        dog.hobby();
        dog['run']();
    </script>

② 构造函数创建对象

<script type="text/javascript">
       function Animal() {
           //设置默认成员(通过this引用)
           this.name="tom";
           this.age=6;
           this.run=function () {
               console.log("在跑步");
           }
       }
        var cat=new Animal();
        console.log(cat);
        cat.run();
    </script>

③ Object方式创建对象

<script type="text/javascript">
        var cat=new Object();
        cat.eat="fish";
        console.log(cat);
    </script>

构造函数与普通函数区别

没有区别,就看使用,new就是构造函数,函数()就是普通函数调用。

函数的各种执行方式

① 普通函数调用

② 构造函数执行new

③ 作为对象的成员方法执行

④ 通过call和apply执行

call和apply可以明显控制变量污染的风险。

call无需声明新的成员出来,就可以直接使用其他函数或方法

<script type="text/javascript">
       var cat={name:"tom",climb:function () {
           console.log(this.name+"在爬树")
       }};
        var dog={name:"旺财",age:6};
        var wolf={name:"灰太狼"};
        cat.climb.call(cat);
        cat.climb.call(dog);

    </script>

apply()方法与call()方法类似,只是将函数test的所有的参数放在一个数组中而已。即:apply()方法只有两个参数,一个是obj对象,另一个是数组,这个数组中存放的是test函数的所有实参。

  • 总结:是为了动态的改变this的指向

this都是谁

① 在函数/方法里边 代表调用该函数/方法的当前对象

② 在事件中,代表元素节点对象

divnode.onclick = function(){
alert(this.value);
}

③ 代表window

④ 可以任意代表其他对象

在call和apply使用的时候,可以任意设置被执行函数内部this的代表

获取构造器

  • 构造器:使用什么元素实例化的对象,元素就称为该对象的构造器

  • 对象.constructor; //获得构造器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值