js问题

java8004 2011-11-01 01:51:02
为什么最后一个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>
...全文
127 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
java8004 2011-11-02
  • 打赏
  • 举报
回复
谢谢各位的精彩回答!~~~~
liangws 2011-11-01
  • 打赏
  • 举报
回复
恩,刚自己测试了一下,确实,不是作用域的问题。我对<script>的理解有误。。。抱歉。。
Legend1988 2011-11-01
  • 打赏
  • 举报
回复
不是作用域的问题,可以在下面的代码添加一个b,结果b输出135.所以这两个其实是一个作用域,不然下面的b定义会覆盖掉135,输出undefined。

<script>
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>

[Quote=引用 9 楼 liangws 的回复:]

引用 4 楼 zsx841021 的回复:

引用 3 楼 yuanzinen56 的回复:

我做了一下测试:
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object……
[/Quote]
MadEric 2011-11-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 liangws 的回复:]

引用 4 楼 zsx841021 的回复:

引用 3 楼 yuanzinen56 的回复:

我做了一下测试:
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object……
[/Quote]
第二个function A(){}定义的时候肯定覆盖第一个了。之所以第一个是ture,是因为alert(a instanceof A);执行的时候第二个<script>块还没有加载好。自始至终只存在一个作用域,只是加载和执行顺序的问题。如果非要说作用域的话,可以说是加载顺序造成的一个临时的作用域。

Legend1988 2011-11-01
  • 打赏
  • 举报
回复
liangws大神又来了,顶一个~
liangws 2011-11-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zsx841021 的回复:]

引用 3 楼 yuanzinen56 的回复:

我做了一下测试:
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object.因为在这个局部作用域中并没有定义a是A的子类。所……
[/Quote]

怎么可能不是作用域的问题呢。。
楼主的例子
第二个function A并没有覆盖第一个function A...都不是同一个作用域的,何为覆盖
alert(a instanceof A);//false
这里为false是因为它指向的是当前动态作用域的函数A
Legend1988 2011-11-01
  • 打赏
  • 举报
回复
不错~[Quote=引用 5 楼 maderic 的回复:]

3楼得解释有点问题,并不是作用域问题,而是<script>块的加载顺序问题。
执行顺序是这样的:
1. 加载第一个<Script>块.
2. function A() {} //定义函数
3. var a = new A(); //实例化一个对象a
4. alert(a instanceof A);//true
5. 加载第二个<script>块.
6. function A() ……
[/Quote]
liangws 2011-11-01
  • 打赏
  • 举报
回复
其实楼主例子改成以下那样会清楚点,然后我再写令一个例子,让大家对比下
例子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函数是作废的,所以打印的结果也是符合的
夕雨峰岩 2011-11-01
  • 打赏
  • 举报
回复
5楼正解
MadEric 2011-11-01
  • 打赏
  • 举报
回复
3楼得解释有点问题,并不是作用域问题,而是<script>块的加载顺序问题。
执行顺序是这样的:
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行的实例
三石-gary 2011-11-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yuanzinen56 的回复:]

我做了一下测试:
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object.因为在这个局部作用域中并没有定义a是A的子类。所以a instanceof A在这里自然返回false……
[/Quote]

说的很明白了。。
yuanzinen56 2011-11-01
  • 打赏
  • 举报
回复
我做了一下测试:
第一个作用域,即在第一个js中,A的type为function,而在这个局部作用域中定义了a是A的子类,所以说用a instanceof A 来测试a是否是A的实例对象,返回true;
而第二个作用域里。A的type还是function.a的type却是默认的object.因为在这个局部作用域中并没有定义a是A的子类。所以a instanceof A在这里自然返回false.
Strive20101101 2011-11-01
  • 打赏
  • 举报
回复
三石-gary 2011-11-01
  • 打赏
  • 举报
回复

87,902

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧