this(函数的上下文)的最终指向和callee,call,ap
2018-01-22 本文已影响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对象