为什么最后一个alert是false?<html>
<script>
function A() {}
var a = new A();
alert(a instanceof A);//true
</script><script>
function A() {}
alert(typeof a);//object
alert(a instanceof A);//false
</script>
</html>
<script>
function A() {}
var a = new A();
alert(a instanceof A);//true
</script><script>
function A() {}
alert(typeof a);//object
alert(a instanceof A);//false
</script>
</html>
http://download.csdn.net/user/Strive20101101
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object.因为在这个局部作用域中并没有定义a是A的子类。所以a instanceof A在这里自然返回false.
执行顺序是这样的:
1. 加载第一个<Script>块.
2. function A() {} //定义函数
3. var a = new A(); //实例化一个对象a
4. alert(a instanceof A);//true
5. 加载第二个<script>块.
6. function A() {} //覆盖第2行的function A(){},因为他们是在同一个作用域,后定义的覆盖先定义的
7. alert(typeof a);//object,因为a是全局的一个对象
8. alert(a instanceof A);//false 因为a是第二行function A(){}的实例,并不是第6行的实例
例子1:<script>
function A() {
this.say = function(){alert(1)};
}
var a = new A();
a.say();// 1
alert(a instanceof A);//true
</script>
<script>
function A() {
this.say = function(){alert(2)};
}
alert(typeof a);//object
alert(a instanceof A);//false
a.say();// 1</script>例子2:
<script>
function A() {
this.say = function(){alert(1)};
}
var a = new A();
a.say();// 2
alert(a instanceof A);//true function A() {
this.say = function(){alert(2)};
}
alert(typeof a);//object
alert(a instanceof A);//true
a.say();// 2
</script>为什么2个例子就差个<script>会有那么大的区别,其实这个要根据作用域来解释的我们先分析例子1:
大家都知道js是一段一段进行语法分析的,包括<script>
所以这2个<script>其实等价于以下例子<script>
//scope1 作用域1
function A() {
this.say = function(){alert(1)};
}
var a = new A();
a.say();// 1
alert(a instanceof A);//true (function(){
//scope2 作用域2
function A() {
this.say = function(){alert(2)};
}
alert(typeof a);//object
alert(a instanceof A);//false
a.say();// 1
})()
</script>改成以上例子后应该比较清楚了吧?
直接可以看出第一个alert(a instanceof A); A函数指向的是作用域scope1的A函数,而第二个alert(a instanceof A); A函数指向的是scope2的函数,因此2个A指向的,都不是不是同一个函数,打印出来的结果当然不一样。(其实这里还需要理解静态作用域与动态作用域,大家有兴趣可以研究下)我们再看例子2:
这里为什么A指向的都是同一个A函数呢?
是因为JS在做语法分析的时候,会对var与function做预解析,所谓的预解析,请看例子
alert(str);//undefined
var str = "123";fn();//ok
function fn(){
alert("ok")
}
其实js在语法分析的时候类似是做了以下操作,alert(str);//undefined
var str = "123";
===>
var str;
alert(str);//undefined
str = "123";fn();//ok
function fn(){
alert("ok")
}
===>
function fn(){
alert("ok")
}
fn();//ok
而function定义的会有以下情况fn();//ok2
function fn(){
alert("ok")
}
fn();//ok2
function fn(){
alert("ok2")
}
这是因为预解析的时候,JS在同一个作用域找到了有多个同名function函数,会把最后面的覆盖前面的函数,因此例子2就可证,后面的A函数覆盖了前面的A函数,前面的A函数是作废的,所以打印的结果也是符合的
怎么可能不是作用域的问题呢。。
楼主的例子
第二个function A并没有覆盖第一个function A...都不是同一个作用域的,何为覆盖
alert(a instanceof A);//false
这里为false是因为它指向的是当前动态作用域的函数A
b=135;
function A() {
this.say = function(){alert(1)};
}
var a = new A();
a.say();// 1
alert(a instanceof A);//true
</script>
<script>
function A() {
this.say = function(){alert(2)};
}
alert(typeof a);//object
alert(a instanceof A);//false
a.say();// 1
var b;
alert(b);</script>