在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而非像C#或其他描述性语言那样仅仅作为一个模块来使用。函数有四种调用模式,分别是:函数调用形式、方法调用形式、构造器形式、以及apply形式。这里所有的调用模式中,最主要的区别在于关键字 this 的意义,下面分别介绍这个几种调用形式。
本文主要内容:
1.分析函数的四种调用形式
2.弄清楚函数中this的意义
3.明确构造函对象的过程
4.学会使用上下文调用函数
一、函数调用形式
函数调用形式是最常见的形式,也是最好理解的形式。所谓函数形式就是一般声明函数后直接调用即是。例如:
复制代码 代码如下:
// 声明一个函数,并调用
function func() {
alert("Hello World");
}
func();
或者:
复制代码 代码如下:
// 使用函数的Lambda表达式定义函数,然后调用
var func = function() {
alert("你好,程序员");
};
func();
这两段代码都会在浏览器中弹出一个对话框,显示字符串中的文字,这个就是函数调用。
可以发现函数调用很简单,就是平时学习的一样,这里的关键是,在函数调用模式中,函数里的 this 关键字指全局对象,如果在浏览器中就是 window 对象。例如:
复制代码 代码如下:
var func = function() {
alert(this);
};
func();
此时,会弹出对话框,打印出 [object Window]。
二、方法调用模式
函数调用模式很简单,是最基本的调用方式。但是同样的是函数,将其赋值给一个对象的成员以后,就不一样了。将函数赋值给对象的成员后,那么这个就不在称为函数,而应该叫做方法。例如:
复制代码 代码如下:
// 定义一个函数
var func = function() {
alert("我是一个函数么?");
};
// 将其赋值给一个对象
var o = {};
o.fn = func; // 注意这里不要加圆括号
// 调用
o.fn();
此时,o.fn 则是方法,不是函数了。实际上 fn 的方法体与 func 是一模一样的,但是这里有个微妙的不同。看下面的代码:
复制代码 代码如下:
// 接上面的代码
alert(o.fn === func);
打印结果是true,这个表明两个函数是一样的东西,但是修改一下函数的代码:
// 修改函数体
var func = function() {
alert(this);
};
var o = {};
o.fn = func;
// 比较
alert(o.fn === func);
// 调用
func();
o.fn();
这里的运行结果是,两个函数是相同的,因此打印结果是 true。但是由于两个函数的调用是不一样的,func 的调用,打印的是 [object Window],而 o.fn 的打印结果是 [object Object]。
这里便是函数调用与方法调用的区别,函数调用中,this 专指全局对象 window,而在方法中 this 专指当前对象,即 o.fn 中的 this 指的就是对象o。
三、构造器调用模式
同样是函数,在单纯的函数模式下,this 表示 window;在对象方法模式下,this 指的是当前对象。除了这两种情况,JavaScript 中函数还可以是构造器。将函数作为构造器来使用的语法就是在函数调用前面加上一个 new 关键字。如代码:
复制代码 代码如下:
// 定义一个构造函数
var Person = function() {
this.name = "程序员";
this.sayHello = function() {
alert("你好,这里是" + this.name);
};
};
// 调用构造器,创建对象
var p = new Person();
// 使用对象
p.sayHello();
上面的案例首先创建一个构造函数Person,然后使用构造函数创建对象p。这里使用 new 语法。然后在使用对象调用sayHello()方法,这个使用构造函数创建对象的案例比较简单。从案例可以看到,此时 this 指的是对象本身。除了上面简单的使用以外,函数作为构造器还有几个变化,分别为:
1、所有需要由对象使用的属性,必须使用 this 引导;
2、函数的 return 语句意义被改写,如果返回非对象,就返回this。
构造器中的 this
我们需要分析创建对象的过程,方能知道 this 的意义。如下面代码:
复制代码 代码如下:
var Person = function() {
this.name = "程序员";
};
var p = new Person();
这里首先定义了函数 Person,下面分析一下整个执行:
1、程序在执行到这一句的时候,不会执行函数体,因此 JavaScript 的解释器并不知道这个函数的内容。
2、接下来执行 new 关键字,创建对象,解释器开辟内存,得到对象的引用,将新对象的引用交给函数。
3、紧接着执行函数,将传过来的对象引用交给 this。也就是说,在构造方法中,this 就是刚刚被 new 创建出来的对象。
4、然后为 this 添加成员,也就是为对象添加成员。
5、最后函数结束,返回 this,将 this 交给左边的变量。
分析过构造函数的执行以后,可以得到,构造函数中的 this 就是当前对象。
构造器中的 return