当调用函数的时候,this参数也将默认的传递给函数。this参数代表函数调用的时候相关联的对象。被称为函数的上下文。
一般,调用函数有以下4中形式:
- 作为一个函数——test()直接被调用
- 作为一个方法——obj.test(),关联在一个对象上。
- 作为一个构造函数——new obj,实例化一个新的对象
- 通过函数的apply或者call方法——test.apply(obj)或者test.call(obj)进行
现在讨论在这四种情况下的this的情况
一、作为函数直接被调用
function test1(){
return this;
}
function test2(){
"use strict";
return this;
}
console.log(test2())
当函数以直接的形式被调用的时候,有两种可能:在非严格模式下,它将是全局上下文(一般而言是window),而在严格模式下,它将是undefined。
二、作为方法被调用
当函数作为某个对象的方法被调用的时候,该对象会成为函数的上下文,并且在函数内部可以通过参数访问到。
function show(){
return this;
}
var myTest = {
getTest:show
}
console.log(myTest.getTest() == myTest);
最终的得到的结果是true,表明this所指向的上下文就是myTest这个对象。
三、作为构造函数调用
function myTest(){
this.show = function (){
return this;
}
}
var obj = new myTest();
console.log(obj.show() == obj)
在这里创建了一个myTest的一个函数作为构造函数,当我们new关键字调用的时候会创建一个空的实例化对象,并且将其作为函数的上下文(this参数)传递给函数。 在这里讨论一下构造函数的返回值问题:
function myTest(){
this.show = function(){
return true;
}
return 1;
}
console.log(myTest() === 1) //true
var test = new myTest();
console.log(test) //myTest { show: [Function] }
console.log(test.show() === 1) //false
console.log(test.show()) //true
从上述代码的执行结果可以看得出,单纯只是在调用myTest函数的时候,返回的结果是1,但是如果将myTest实例化以后并调用其show方法,结果就是show方法的返回值。再做下面一个测试:
var test1 = {
shuxing1 : true
}
function myTest(){
this.shuxing1 = false;
return test1;
}
var aa = new myTest();
console.log(aa) //{ shuxing1: true }
console.log(aa.shuxing1) //true
这里,在构造函数内返回了一个对象test1,然后调用了myTest的构造方法,但这时,构造函数的返回值变成了test1这个对象。所以,输出的实例化对象中,aa变成了test1类。总结以上两点就是:
- 如果构造函数返回一个对象,则该对象将作为整个表达式的返回值,而传入的构造函数this将被丢弃。
- 但是,如果构造函数返回的是非对象类型,则会自动忽略这个返回值,返回新创建的对象。
四、使用apply或者call方法调用
javascript提供了与一种方法可以显示的指定任何对象作为函数的上下文。利用apply或者call方法即可实现,调用这两个方法的时候,需要传入两个参数:作为函数上下文的对象和作为函数调用时的一个数组对象。下面是这个例子的实例:
function addSum(){
var result = 0;
for(var i = 0;i < arguments.length;i++){
result += arguments[i];
}
this.result = result;
}
var test1 = {}
var test2 = {}
addSum.apply(test1,[1,2,3,4,5]);
addSum.call(test2,1,2,3,4,5);
console.log(test1.result); //15
console.log(test2.result) //15