测试用例1
今天在写 websocket 的 demo 的时候,很随意的定义了 send 和 close 方法,来发送数据和关闭连接。大致代码如下
<html>
<head>
<meta charset="utf8">
<script>
function send() {
console.log("send");
}
function close() {
console.log("close");
}
</script>
</head>
<body>
<button onclick="send()">send</button>
<button onclick="close()">close</button>
</body>
</html>
照理说,这段代码应该没什么问题,但是 close 却不会被调用。
后来发现,调用的是 document 下的 close 方法(点击箭头加三横线可以转到方法的定义,系统的方法无法跳转,仅能转到我们自己写的代码)
删掉代码中定义的 close 方法,刷新页面后再次在控制台上打印 window.close 和 document.close 可以看到两者皆有定义。
元素内嵌事件,在调用时,查找的顺序是:
- document 对象下是否有该方法
- 用户是否有在全局定义该方法(全局定义的方法被挂在window对象下)
- window 对象下是否有定义该方法
测试用例2
为了证明上述结论,再写一个测试用例
<html>
<head>
<meta charset="utf8">
<script>
window.test = function() {
console.log("window's test");
}
document.test = function() {
console.log("document's test");
}
test();
</script>
</head>
<body>
<button onclick="test()">test</button>
</body>
</html>
可以看到
- 在 javascript 中调用和定义,默认用的是window下的方法
- 在html节点中定义的方法,会优先到document对象中查找,然后才是window对象
测试用例3
再试一下显式赋值给 window
<html>
<head>
<meta charset="utf8">
<script>
window.test = function() {
console.log("window's test");
}
document.test = function() {
console.log("document's test");
}
function test() {
console.log("javascript's test");
}
test();
window.test();
</script>
</head>
<body>
<button onclick="test()">test</button>
</body>
</html>
本来以为后面定义的 test 方法,会覆盖掉 window.test 方法,结果却大出意料!!!、
(交换 test 和 window.test 的定义顺序,打印依旧不变)
这说明显式给window指定的对象,会覆盖隐式指定的对象,而与定义的先后顺序无关
删掉 window.test 的定义之后,再次打印