js函数上下文

函数的上下文是什么,取决于函数怎么调用而不是函数如何定义

函数用圆括号调用,函数的上下文是window对象;

1
2
3
4
5
6
7
function f() {
var a = 1;
console.log(this.a);
}
var a = 2;
f();

函数 f()的中的this指代谁,不要看这个函数是如何定义而是看怎么调用。此时f()的上下文是window对象。
所有的全局变量都是window对象的属性,(注意:函数里面的局部变量,不是window属性,不是任何对象的属性,它就是一个变量!)

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

1
2
3
4
5
6
7
8
9
function f() {
console.log(this.a);
}
var o = {
"a" : 1,
"b" : 2,
"c" : f
}
o.c();

此例f()定义出来又把这个函数绑定给了对象o的c属性,调用的时候是对象打点调用,函数中的this是这个o对象。

函数是事件处理函数,函数的上下文就是触发这个事件的对象;

1
2
3
4
5
6
7
8
9
10
11
function f() {
this.style.background = '#f00';
}
//页面中创建三个div id分别为 col1, col2, col3;
var col1 = document.getElementById('col1');
var col2 = document.getElementById('col2');
var col3 = document.getElementById('col3');
col1.onclick = f;
col2.onclick = f;
col3.onclick = f;

函数不会自动执行,直到用户点击触发事件,点击哪个html标签,this就指代哪个html标签。

定时器调用函数,上下文是window对象

1
2
3
4
5
6
function f() {
console.log(this.a);
}
var a = 1;
setInerval(f,1000);

函数f被定时器调用,此时函数上下文就是window对象,每秒在控制台输出一个1。

数组中存放的函数,被数组索引调用,上下文就是这个数组;

1
2
3
4
5
6
function f() {
console.log(this.length); //3
}
var arr = [f, '1' , '2'];
arr[0]();

此时这个函数是从数组中枚举处理的然后加()执行的,最终调用的是这个数组,this代指这个数组。

apply和call这两个函数打点调用,表示用指定的上下文来执行这个函数

1
2
3
4
5
6
7
8
9
10
11
12
function f(a, b , c) {
console.log(a+b+c)
console.log(this.a);
}
var o = {
'a' : 1,
'b' : 2
}
f.call(o, 4, 5, 6); // 15 1
f.apply(o, [4, 5, 6]); //15 1

函数的调用方式:
圆括号直接调用;
对象打点调用;
定时器调用
事件处理函数调用;
数组枚举调用
他们体现的不同点就是函数的上下文不同,他们的this不同。