我对javascript函数的理解

来源:互联网 发布:淘宝购买mycard 编辑:程序博客网 时间:2024/05/17 21:50

javascript的函数定义有以下四种形式:


function func1(…){…}
var func2=function(…){…};
var func3=function func4(…){…};
var func5=new Function();


首先在javaccript里,函数是核心,javascript用函数构造了javascript的对象,所以说函数在javascript中是一种最底层的,最基本的存在形式。 函数本身是一个对象,它的类型是Function。它同时也是一个对象构造器,可以用new一个函数返回一个对象,这个特性用来实现javascript的面向对象特性。


function func1() {alert("hello world");}func1();

最简单的函数调用,运行结果是弹出hello world 对话框。

function func1() {alert("hello world");}new func1;

结果和上一段代码一样,弹出hello world对话框。 这里说明了,可以用new 一个函数,返回一个对象,new调用了构造器,func1花括号中的代码,就是这个函数的构造器函数。

new func1 返回了一个由func1构造器函数初始化的一个对象。


function func1() {alert("hello world");}var func2 = new func1;alert(typeof(func2));

这里,typeof的结果是 Object,说明 new func1返回了一个Object类型的对象,从这里可以看出,函数的实质就是一个构造器,而当在构造器中不指定返回类型的话,默认返回的是这个对象本身,以正常的逻辑这里的这个对象本身应该指的是一个函数(即Function类型),可实际结果确实返回的是一个Object类型,这就说明javascript在这里把函数看作了一个纯粹的为了构造对象的构造器方法 ,new func1实际上是先new了一个空对象,然后在这个空对象上调用func1函数,以达到初始化这个空对象的目的。

function func1() {alert("hello world");return this;}var func2 = new func1;alert(typeof(func2));alert(typeof(func1));

返回结果是 func2为Object类型,func1是Function类型。


function func1() {alert("hello world");return this;}var func2 = func1();alert(typeof(func2));alert(typeof(func1));

结果和上一段代码一样,那么()调用和 new的区别是什么呢? 看如下代码
function func1() {alert("hello world");}var func2 = func1();alert(typeof(func2));alert(typeof(func1));

这里,我把func1函数定义中的return this去掉了,结果发生了变化,typeof(func2)返回的结果变成了undefined而不是原来的Object。 所以说()调用与new的区别就在于,()只是单纯的调用,如果构造器没有指定返回值的话,就没有返回值即返回结果年是void,而new调用构造器的时候,当构造器没有return语句,还是会返回一个对象,因为new命令创建了一个对象,function只是用来为这个对象初始化的。


虽然看了一些资料,都说function func1(){} 这句话相当于创建了一个函数对象,javascript里把函数看作是一个对象可以方便的赋值给变量或者作为参数传递,但是下面的代码说明它会对象还是有一点区别,目前位置没有找到资料来解释这个问题。


function func1() {    alert("hello world");    this.func3=function(){        alert("I'm function 3")    }    //return this;    }func1();func1.func3();

上面的代码执行后 不会弹出任何“I‘m function 3”对话框,也就是说 如果func1是一个对象的话,作为这个对象的一个一个属性的func3函数应该可以被调用到,而在这里这里func3没有定义。然后我们修改上面代码如下:


function func1() {alert("hello world");this.func3=function(){alert("I'm function 3")}return this;}var func2 =func1();func2.func3();

我在 函数定义中加入了一个return this 语句,使调用调用这个函数返回一个函数对象,这次可以调用到 func3函数了,说明func1()返回的才是真正的函数对象,它和单纯的func1函数名还是有一定的区别。 现在我们再来讨论一下 new,和 () 调用的一点区别。

function func1() {alert("hello world");this.func3=function(){alert("I'm function 3")}return this;}alert(typeof(func1()));alert(typeof(new func1));

两个typeof在返回类型上都是Object,说明无论是()还是new都会在一个空Object上调用func1。下面的代码演示了它们俩的细微区别

这里我的理解有一点错误, ()调用函数的时候,并不是在一个空Object上调用一个func1,而是在window对象上,这个对象是整个javascript运行的上下文环境。可以用firefox浏览器的firebug设置断点,然后在变量监控窗口下看this到底是一个什么东西。

function func1() {var a = 1;alert("hello world");this.func3=function(){a++;alert(a);}return this;}var funcA = func1();var funcB = func1();funcA.func3();funcB.func3();

这段代码的执行结果是,先后弹出 窗口 “2” ,“3”。这说明两次调用func1()返回的对象是同一个函数对象,两次调用a++ 都是在同一个变量上相加。在看使用new的情况:



function func1() {var a = 1;alert("hello world");this.func3=function(){a++;alert(a);}return this;}var funcA = new func1;var funcB = new func1;funcA.func3();funcB.func3();


代码的执行结果是 弹出两个相同的“2” 窗口,说明new func1;返回了两个不同的函数对象。 其实这里这么来描述应该不准确。 因为此处var a定义的并不是对象的属性,而是在函数作用域内的一个临时变量,出了这个函数,就无法再访问a变量了。a变量应该是在函数运行的上下文环境中。func3之所以能访问var a,用专业一点的术语讲,就是闭包。

function func1() {this.a = 1;alert("hello world");this.func3=function(){this.a++;alert(this.a);}return this;}var funcA =  func1();var funcB =  func1();funcA.func3();funcB.func3();

试着把var a 变量改成this.a 发现运行结果和使用var a变量没有区别,用()时 两次调用访问同一个变量a, 用new时候 两次两次调用访问的是各自的a变量。 这里有个疑问,当用()调用的时候,this指代的到底是一个什么对象?

原创粉丝点击