setTimeout第一个参数执行域的问题

最开始写的代码是这样的,后来找到原因说setTimeout是window方法,而a是私有域里的,所以找不到。
(function a(){
document.write('1');
setTimeout('a()',2000);
})();
但为什么改为下面的写法就可以了呢?
(function a(){
document.write('1');
setTimeout(a,2000);
})();
不介意多讲讲,谢谢。

setTimeout函数的第一个参数可以是Function, 也可以是String代码字符串。string写法是不推荐的,但可以运行。如果是传入string,解析后变量的作用域就找不到了,只能直接在全局作用域中查找,这跟setTimeout是全局函数没有关系;你的第二种写法是传递的Function,它会从当前作用域向上查找。实名函数在自身作用域内可以调用自己,递归函数就经常这样写function a() {a();};所以setTimeout 可以调用它,a里面所有函数都能调用a。

第一种写法是有问题的。setTimeout('a()',2000);加了引号就跟字符串一样,不是一个函数,而且你这是准备干吗?为什么会把调用的方法放在方法内部??没看太懂,不应该是定义一个函数,在其他地方进行调用吗?

你这问的,跟setTimeout这个方法没有关系,是JS参数语法的问题,你把变量用字符窜包起来系统不就认为你传进来的是字符窜吗,所以就没有达到你预期的效果,是你自己本身理解不够的问题

加了单引号,就变成字符串了,定时器的第一个参数应该是个函数
(function a(){
document.write('1');
setTimeout(a,2000);
})();
自执行函数(function(){})()
一开始你先执行函数a所以页面显示1
然后定时器里你有回调了函数a啊,就构成了一个不断的循环。
页面显示的效果就是一开始有一个1,然后每延时2秒就多一个1.

首先,你要的效果是每隔两秒往页面里输出一个1

那么你在settimeout里面的函数写法有问题,第一种写法,‘a()’这是一个字符串,虽然后来又被解析了,但是这时候已经是两秒以后了,这时候并不是说a是私域里的变量所以找不到之类的,而是因为你这里找的是'a' 而不是a 这两个是有本质上的区别的,一个是字符串,一个是变量。
第二,如果按照你的写法,把这里改正过来,写成setTimeout(a(),2000); 这样就更加不对了,这里估计你自己也明白,在这里a函数直接就被执行了,而不是等到两秒以后才执行,所以这样写直接就死循环了。所以这样写也是不行的
第三,改成第二种写法,这时候setTimeout里面的a代表的就是a函数,所以会每隔两秒钟调用一次,这是正确的

里面要用函数名吧,上面讲的都很好!!!

js里还是有面对对象思想的,每个定义的function ,其原型都是Function ,即都是Function 构造器的对象,而函数名就是该对象的引用,可以看下我这篇日志:http://blog.csdn.net/qq_19865749/article/details/52811358

1),你自己也说了是()括起后a是私有setTimeout第一个参数是字符串时,调用到的函数必须是window作用域下的,所以访问不到a函数

2)函数作为setTimeout参数时,内部肯定可以访问到a函数,在同一个作用域内,所以不会报错