前面的话
函数作为任意一门编程语言都是核心。想精通js,在这方面多下功夫是必须的。JavaScript中函数既对象,这篇文章是小柒看过很多博客之后总结出来的。
函数调用的4种模式
● 作为普通函数调用
● 作为对象的方法调用
● 构造函数调用
● call与apply方法的间接调用
作为普通函数调用
function add(x, y) {
return x + y;
}
var sum = add(1, 2);// 这就是普通的函数调用
console.log(sum);
使用普通函数的调用时,在非严格模式下,this被绑定到全局对象
在严格模式下,this是undefined。
function add(x, y) {
console.log(this);//window
}
add();
function add(x, y) {
'use strict';
console.log(this);// undefined
}
重写
普通函数的调用this会绑定到全局对象window,所以全局变量可以被重写
var a = 0;
function fn() {
this.a = 2;
}
fn();
console.log(this, this.a, a);// window 2 2
作为对象的方法调用
当一个函数作为一个对象的属性时,可以称为这个函数是对象的方法。当方法被调用时this被绑定到该对象上。
var obj = {
fn: function() {
console.log(this);// {fn:f}
};
obj.fn();// 这就是作为一个对象的方法调用,此时this指向的就是obj这个对象
作为对象的方法调用,此时通过this可获取或改变对象的属性值
var obj = {
a : 1,
m: function() {
return this;
},
n: function() {
this.a = 2;
}
}
console.log(obj.m().a);// 1
obj.n();
console.log(obj.m().a);// 2
注意:与变量不同是this没有作用域的限制,嵌套函数不会从调用它的函数中继承this.
如果嵌套函数作为对象的方法调用,那么其this指向调用该方法的对象;
如果嵌套函数作为普通函数调用,那么在非严格模式下,指向window,在严格模式是undefined
var obj = {
m: function() {
function n () {
return this;
}
return n();// 作为普通函数调用
}
}
console.log(obj.m());// window
如果想访问外层的this可以将其保存起来
var obj = {
m: function() {
var that = this;
function n() {
return that;
}
return n();
}
}
console.log(obj.m() === obj);// true
构造函数模式
如果函数或者方法调用之前有new关键字,它就是构造函数的调用
function fn() {
this.a = 1;
}
var obj = new fn();
console.log(obj.a);//1
/*
构造函数通常没return关键字,这种情况下构造函数调用会返回一个新的对象,构造函数的this 将指向这个对象
function fn() {
this.a = 2;
}
var test = new fn();
console.log(test);// {a:2}
当构造函数有return关键字,但无返回值时,this仍指向new fn()返回的新对象
function fn() {
this.a = 2;
return ;
}
var test = new fn();
console.log(test);// {a: 2}
当构造函数有return关键字,且返回一个对象。那么此时不会产生新的对象,test的值就是返回的obj对象
function fn() {
this.a = 2;
return obj;
}
var test = new fn();
console.log(test);// {a: 1}
call与apply方法的间接调用
函数本生也是对象,每个函数都有call()与apply()方法。使用它们将可以间接调用函数 ,call()与apply()可以改变this指向。两个方法的作用是相同的,只是参数列表不同。
详解call()与apply()可以查看小柒的另一篇文章“深入理解call()与apply()”
var obj = {};
function sum(x, y){
return x + y;
}
console.log(sum.call(obj,1,2));// 3
console.log(sum.apply(obj,[1,3]));// 4
参考:
阮一峰老师的文章:http://javascript.ruanyifeng.com/grammar/function.html
其他优秀的文章:
http://www.cnblogs.com/xiaohuochai/p/5702813.html#anchor1