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

2018-01-22  本文已影响0人  _嗯_哼_

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

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对象

上一篇下一篇

猜你喜欢

热点阅读