js做用域问题

<script type="text/javascript">
            alert(i);//Uncaught ReferenceError: i is not defined
            i=11;
           </script>

 

<script type="text/javascript">
            alert(i);//undefined
            var i=11;
            alert(i);//11
            </script>

 

 

 

 

代码1:javascript

var name="hello"
function f1(){
    console.info(name);
    var  name="world";
    console.info(name);
}
f1();

输出结果:java

undefined;

world;

 

 

代码2:编程

var name="hello"
function f1(){
    console.info(name);
}
f1();

输出结果:函数

hello

 

 

复制代码
var param = 1; function main() { console.log(param); var param = 2; console.log(this.param); this.param = 3; } //下面两条语句分别会在控制台打印什么? main(); var m = new main();
复制代码

 

讲解以下:this

1. main() , 打印的结果为: undefined1spa

 

a. >  来看第一个打印的值为何是 undefined。 在js中,方法和变量的声明都是会提早的。也就是说无论你在何处声明的方法或者变量,在js解析时,都会将其提早,具体看代码prototype

复制代码
demo(); //此处能正常弹出 similar function demo() { alert("similar"); }
复制代码

按照js的语句执行顺序,应该是从上自下依次执行的。 也就是说会先执行demo(), 然而这个时候demo()尚未声明,并不存在,应该报错才对,为何还能正常弹出similar呢?这就前面说的方法声明在js解析时会提早。因此上面 的代码,通过解析以后,就至关于code

复制代码
function demo() { alert("similar"); } demo(); //此处能正常弹出 similar
复制代码

因此才会正常弹出 similar。 那么对于变量的声明也是同样的,会提早。 咱们上面的代码,通过解析以后实际上等同于下面的代码对象

复制代码
var param; //声明提早 param = 1; function main() { var param; //声明提早 console.log(param); //由于此时 param 只是进行了声明,并未赋值,因此 打印的是 undefined param = 2; console.log(this.param); this.param = 3; }
复制代码

这里你或许会感到疑惑。咱们在main()方法外面不是已经赋值为1了吗?  这是由于,咱们在main()方法里面也定义了一个同名的 param。 就近原则,js会先查找本身有没有这个变量,若是有,就用本身的,若是没有就向上级查找,上级仍是没有就到上上级去查找,如此循环,在哪找到,就在哪停 止。若是全都没有,就返回undefined。 【这里涉及到一个知识点: js做用域链及变量查找, 以后我会写一篇于此相关的讲解文章】blog

 

b. > 如今咱们再来看看第二打印的值为何是1。 我将代码再作一次等价转换,这样或许你们就更容易明白原因了,转换后代码以下

复制代码
window.param = 1; //全局变量 param // 全局方法 main() window.main = function () { console.log(param); var param = 2; console.log(this.param); //此时的this指代的就是 window, 所以 this.param = window.param = 1 this.param = 3; } 
//调用全局方法main() window.main();
复制代码

看到这里,你们是否有些明白了呢?由于 main() 方法和 main() 方法外面的 param 都是定义在最外层的(没有包裹在其余对象里面),所以他们都是全局对象window下的成员。 当咱们调用 main() 方法时, 实际上就是调用的 window.main();  而经过这样的方式调用时, this 指代的就是全局对象 window。 因此第二个打印的值为 1。【这里涉及到一个知识点: js中让人迷糊的this,以后我会写一篇于此相关的讲解文章】

 

2. var m = new main(), 打印的结果为: undefinedundefined

 

a. > 第一个打印的值为 undefined 的缘由和上面的缘由是同样的,都是由于变量声明提早致使的。

 

b. > 那么第二个打印的值也为 undefined 的缘由是什么呢? Js也是支持面向对象式编程的语言,然而js中却没有类的概念,而是使用基于原型(prototype)的继承。 所以呢,js中的构造函数也很特别,通常状况下它和普通方法没什么区别,只有经过 new 关键字来调用的时候才能体现出其做为构造函数的功能。 而此处正是把 main() 和 new 关键字一块儿使用,说明此时的main()是一个构造函数。而构造函数中的 this 指代的就是新建立的对象,那么也就是 m 。

复制代码
var param = 1; function main() { var param; //声明提早 console.log(param); //由于此时 param 只是进行了声明,并未赋值,因此 打印的是 undefined param = 2; console.log(this.param); //构造函数中的this指代的是新建立的对象,咱们这里新建立的对象是 m , 因此 this.param = m.param , 而此时 this.param 还没有赋值,因此打印的是 undefined (此处我本身也有一个疑问: 构造函数中的属性的声明会提早吗?也就是 this.param 的声明会提早吗? 求解) this.param = 3; } var m = new main();
复制代码
相关文章
相关标签/搜索