论坛首页 Web前端技术论坛

Javascript笔记之 函数中的this

浏览 3196 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-06-02  

这个很有搞头,简单看两个例子,说说我个人的理解吧:

 

例一.

 

var aa=11; 
Test(); 
alert(aa);

function Test() 
{ 
  var aa=33; 
  alert(this.aa);
  this.aa = 22; 
  alert(this.aa);
  alert(aa);
} 

alert(new Test().aa);

 

这段代码运行结果是:

[11] [22] [33] [22] [undefined] [22] [33] [22]

 

一点个人理解:

  • 这段带码运行在window对象上,浏览器似乎将var定义的变量全部当成window对象的属性,若一个变量未用var定义,却在程序中被赋值,那么浏览器将先为window对象创建该属性,并给该属性赋值;
  • 任何函数中的this代表调用该函数的对象,如果没有任何对象调用该函数(直接让函数执行),那么就相当于是window对象调用该函数执行(其中的this就代表window对象);
  • 对于new Test()这样的写法其实可以看做新建一个空对象,然后让该空对象调用Test()函数;在悟透javascript一书中李占说:var aObj = new func()就等价于 var aObj = {}; func.call(aObj);

代码第一次调用Test()时,this对应的对象是window,第二次this对应的对象是一个匿名的Object。

 

 

例二.

 

var Foo = {Name:'Foo'};

function OuterFoo()
{
	this.Name = 'Outer Name';
	function InnerFoo()
	{
		var Name = 'Inner Name'; 
		alert(Name + ', ' + this.Name);
	}
	
	return InnerFoo;
}

(new OuterFoo())();               // 直接调用InnerFoo, 但是为OutFoo创建了调用对象
alert(window.Name);             // 由于OutFoo有了调用对象, 故而不会为window对象创建Name属性
OuterFoo()();                         // 直接调用InnerFoo, 并且也直接调用了OutFoo
alert(window.Name);            // 由于直接调用了OutFoo, 所以也为window对象创建Name属性并赋值
(new OuterFoo()).call(Foo);  // 用Foo对象调用InnerFoo, InnerFoo当然也就获得了其Name属性

 

这段代码运行结果是:

[Inner Name, undefined] [undefined] [Inner Name, Outer Name] [Outer Name] [Inner Name, Foo]

 

简单分析见注释部分。

 

总而言之,function中的this指向调用它的对象, 默认的调用它的对象为window。

呵呵,刚刚看到其他的帖子这样描述this:有奶就是娘,很贴切啊!

还有其他的一些常见的讨论,见下面的讨论贴:

http://www.iteye.com/topic/189102

http://www.iteye.com/topic/122569

 

   发表时间:2009-06-03  
好文章~~学习学习

最后那有一点不怎么懂!
(new OuterFoo()).call(Foo);  // 用Foo对象调用InnerFoo, InnerFoo当然也就获得了其Name属性  

这句是如何执行的?
0 请登录后投票
   发表时间:2009-06-04  
wnzz95391511 写道
好文章~~学习学习

最后那有一点不怎么懂!
(new OuterFoo()).call(Foo);  // 用Foo对象调用InnerFoo, InnerFoo当然也就获得了其Name属性  

这句是如何执行的?

 

可以先alert(new OuterFoo());

看到返回的是[function InnerFoo(){var Name = 'Inner Name'; alert(Name + ', ' + this.Name);  }]

个人感觉 new Func() 时,若Func有返回值且返回值为function或是object类型的话,则返回其返回值,否则,则返回一个空对象{}调用Func之后自身所转变成的对象,相当于:

function New(Func)

{

var y = {};

var z = Func.call(y); // 返回OutFoo的返回值

if((typeof(z)=="function") || (typeof(z)=="object")) return(z);

else return(y);

}

 

这样就比较容易理解,等于就是InnerFoo.call(Foo);

0 请登录后投票
   发表时间:2009-06-04  
sfh 写道
wnzz95391511 写道
好文章~~学习学习

最后那有一点不怎么懂!
(new OuterFoo()).call(Foo);  // 用Foo对象调用InnerFoo, InnerFoo当然也就获得了其Name属性  

这句是如何执行的?

 

可以先alert(new OuterFoo());

看到返回的是[function InnerFoo(){var Name = 'Inner Name'; alert(Name + ', ' + this.Name);  }]

个人感觉 new Func() 时,若Func有返回值且返回值为function或是object类型的话,则返回其返回值,否则,则返回一个空对象{}调用Func之后自身所转变成的对象,相当于:

function New(Func)

{

 

var y = {};

var z = Func.call(y); // 返回OutFoo的返回值

 

if((typeof(z)=="function") || (typeof(z)=="object")) return(z);

else return(y);

}

 

这样就比较容易理解,等于就是InnerFoo.call(Foo);

 

嗯,这下有点理解了~~~感谢!

0 请登录后投票
   发表时间:2009-06-05  
(new OuterFoo())(); //利用匿名对象调用OuterFoo生成InnerFoo,再利用window对象去调用InnerFoo, 
                    //因为window.Name为undefined,所以得出Inner Name,undefined;
alert(window.Name); //如上所说:undefined
OuterFoo()();       //利用window对象去调用OuterFoo,第一个this.name相当于window.name,
                    //然后继续用window对象去调用InnerFoo, 得出Inner Name,OuterName
alert(window.Name); //window.Name已经在上面被赋值了,即OuterName
(new OuterFoo()).call(Foo);  //先利用匿名对象调用OuterFoo生成InnerFoo,再用Foo对象调用InnerFoo, 得出Inner Name,Foo

0 请登录后投票
   发表时间:2009-06-06  
司徒正美 写道
(new OuterFoo())(); //利用匿名对象调用OuterFoo生成InnerFoo,再利用window对象去调用InnerFoo, 
                    //因为window.Name为undefined,所以得出Inner Name,undefined;
alert(window.Name); //如上所说:undefined
OuterFoo()();       //利用window对象去调用OuterFoo,第一个this.name相当于window.name,
                    //然后继续用window对象去调用InnerFoo, 得出Inner Name,OuterName
alert(window.Name); //window.Name已经在上面被赋值了,即OuterName
(new OuterFoo()).call(Foo);  //先利用匿名对象调用OuterFoo生成InnerFoo,再用Foo对象调用InnerFoo, 得出Inner Name,Foo

 

 

呵呵,解释的很详细,我说的太笼统了~

0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics