美文网首页
this(函数的上下文)的最终指向和callee,call,ap

this(函数的上下文)的最终指向和callee,call,ap

作者: _嗯_哼_ | 来源:发表于2018-01-22 23:04 被阅读0次

    this对于很多新手玩家来说,是一个难点,而且在面试题中也会被this给虐成狗~下面就具体看看this到底有多6

    • 记住this最终指向它的调用者(只有函数在调用了之后才会有this的存在)
      规律一:函数用圆括号调用,函数上下文是window对象
    function fun() {
            var a=100;//局部变量不属于任何对象的属性,只是存放在内存中的堆里
            alert(this.a)
        }
        var a=200;
        fun()//200
    //结论:此时是window在调用fun函数,相当于window.fun(),window此时隐藏了而已
    

    规律二:函数如果作为一个对象的方法,对象打点调用,函数上下文就是这个对象

    function fun() {
            var a=888;
            alert(this.a)
        }
    
        var obj={
            "a":10,
            "b":20,
            "c":fun
        }
        obj.c();//10
    

    规律三:函数是事件处理函数,函数的上下文就是触发这个事件的对象

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            div{
                width: 50px;
                height: 50px;
                background:pink;
            }
        </style>
    </head>
    <body>
        <div id="box"></div>
    </body>
    <script type="text/javascript">
        function fun() {
            this.style.background="red"//this表示box,点击box变红
        }
    
        var box=document.getElementById("box");
        box.onclick=fun;
    </script>
    </html>
    

    此时如果有多个盒子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            div{
                width: 50px;
                height: 50px;
                background:pink;
            }
        </style>
    </head>
    <body>
        <div id="box1"></div>
        <div id="box2"></div>
        <div id="box3"></div>
    </body>
    <script type="text/javascript">
    
        function fun() {
            this.style.background="red"//此时this代表的是各自box,
        }
    
        var box1=document.getElementById("box1");
        var box2=document.getElementById("box2");
        var box3=document.getElementById("box3");
        box1.onclick=fun;
        box2.onclick=fun;
        box3.onclick=fun;
    
    </script>
    </html>
    

    规律四:定/延时器调用函数,this是window对象

    function fun() {
            console.log(this)
        }
        setInterval(fun,1000)
    
    image.png

    考考你:结合规律三

    var box=document.getElementById("box");
    box.onclick=function(){
            //var self=this;如果想this不变,得用变量先存起来(sleft.style.background="red")
        setTimeout(function(){
        this.style.background="red"
         
        },1000)
    }
    //结论:此时会报错,因为此时的this是window
    

    规律五:数组中存放的函数,被数组索引调用,this就是这个数组

    function fun(a,b,c,d,e,f){
            alert(this.length)
        }
        var arr=[fun,"dd","cc"]//数组长度是3
        var length=10;
        arr[0]();//3
    

    小测试:先自己思考,记下答案,我会把答案放在文末
    1

    function fn(){
            alert(this.a)
        }
        var obj={
            "a":1,
            "b":2,
            "c":[{
                "a":3,
                "b":4,
                "c":fn
            }]
        }
        var a=5;
        obj.c[0].c()    
    

    2 :arguments见上篇

    function fn(m,n,o,p,q,r){
            alert(this.length)
        }
    
        function fun(a,b){
            arguments[0](9,10,11,12,13)
        }
    
        fun(fn,5,6,7)  
    

    解释一下arguments.callee

    function fun(a,b,c,d,e,f){
            console.log(arguments.callee===fun);//true,表示的是函数自身
            console.log(arguments.callee.length);//6 表示函数自身,自身长度就是形参
            console.log(arguments.length);//3  表示的是实参个数
        }
        fun(55,66,77)
    

    call和apply的异同点

    :二者都是函数对象的方法,只能是函授打点调用~,表示用指定的上下文执行这个函数;

    function fun(){
            alert(this.age)
        }
        var obj = {
            name:"xj",
            age:"24",
            like:"play"
        }
        fun()  //undefined
        fun.apply(obj) //24
        fun.call(obj)  //24
    

    :apply只接受数组,call只接受用逗号分割的参数

    function fun(a,b,c){
            alert(a+b+c)
        }
            var obj={
                name:"xj",
                age:24
            }
        fun.call(obj,6,7,8)  //21
        //fun.apply(obj,6,7,8) //报错
        fun.apply(obj,[6,7,8])//21
    

    应用:
    1、求最大值:
    Math.max(3,4,5,6)//6
    2、求一个数组的最大值
    Math.max.apply(window,[4,5,6,7,8])//8

    》》》》》》》小测试答案《《《《《《《《
    1、3 //结论:函数的最终调用者是对象c
    2、4 //结论:函数最终调用。是arguments对象进行方括号索引得到的这个函数,然后加圆括号调用了,所以符合规律2,或者规律5;如果你认为argument是对象,规律2生效,如果认为argument为数组,规律5生效;所以无论如何:函数fn里面的函数是argument对象

    相关文章

      网友评论

          本文标题:this(函数的上下文)的最终指向和callee,call,ap

          本文链接:https://www.haomeiwen.com/subject/wemraxtx.html