自执行块内的Javascript函数不可访问.为什么
Javascript functions within self-executed block not accesible. Why?
我有一个简单的index.html文件,其中包含一些可拖动的图像。我的JS文件看起来像这样:
function drop(ev){
ev.preventDefault();
var data = ev.dataTransfer.getData('text');
ev.target.appendChild(document.getElementById(data));
}
function drag(ev){
ev.dataTransfer.setData('text',ev.target.id);
}
这很好。但是,正如我所学到的,在一个自执行的块中编写代码是一个很好的实践。
我移动了两个函数:
(function(){
function drop(ev){
ev.preventDefault();
var data = ev.dataTransfer.getData('text');
ev.target.appendChild(document.getElementById(data));
}
function drag(ev){
ev.dataTransfer.setData('text',ev.target.id);
}
})();
现在,当拖动图像时,函数似乎是"未定义的"。它们可能是新手问题,但是:
我可以保持我的函数在块范围内,仍然在HTML上使用它们,如
<div id="div0" ondrop="drop(event)">...</div>
?如果没有,为什么?
把东西封闭到生命里的全部意义在于隔离它们,不让不必要的东西污染全球环境。例如,
var counter = (function() {
var current = 0;
function getCurrentAndIncrement() {
return current++;
};
return getCurrentAndIncrement;
})();
counter()
// 0
counter()
// 1
current
// ReferenceError: current is not defined
我们隐藏了应该是私有的,而暴露了应该是公共的。
你把所有的东西都藏起来了——那么它是不可接近的这一事实就不足为奇了。
最后,<div id="div0" ondrop="drop(event)">...</div>
是一个不好的实践。从JavaScript中绑定事件监听器要好得多,虽然有点复杂。这样做:
<div id="div0">...</div>
然后在JavaScript中,
var div0 = document.getElementById('div0');
div0.addEventListener('drop', myHandler);
,这确实可以塞进IIFE。无论你从HTML中引用什么(如在你的drop
函数中)都需要在全局范围内,否则浏览器将无法找到它。
答案是scope。在函数中定义的变量和函数只能在该函数中访问。在你的第一个例子中,你是在全局定义它们;在第二个示例中,它们位于函数内部。
我可以保持我的功能在块范围内,仍然使用他们的HTML像
<div id="div0" ondrop="drop(event)">...</div>
?
要使用老式onxyz
属性处理程序中的函数,它们必须是全局的。你可以把你的函数赋值给全局对象的属性,使它们成为全局的,你可以在浏览器上以window
的方式访问它们:
(function() {
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData('text');
ev.target.appendChild(document.getElementById(data));
}
function drag(ev) {
ev.dataTransfer.setData('text', ev.target.id);
}
window.drop = drop;
window.drag = drag;
})();
…但理想情况下,创建全局变量最好是而不是;全局命名空间非常拥挤,添加到其中只会引起冲突。相反,使用现代事件处理(addEventListener
, attachEvent
)代替onxyz
属性。
内部函数不会被执行。闭包的美妙之处就在这里了让js对象private & &;公众。这段代码可以满足您的目的
var demoFunction =(function(){
function _drop(ev){
alert("Helo");
_drag();
}
function _drag(ev){
alert("Hello1");
}
_drop();
return{
drop :_drop,
drag:_drag
}
})();
你也可以通过demoFunction从其他函数调用这个拖放操作。下降,等等。希望这对你有帮助。
jsfiddle
- 为什么在这个网站上不能通过JS访问元素
- 为什么可以't PHP查找可以使用JS或jQuery访问的元素
- 为什么可以't我访问Chrome内置功能$
- 为什么在中声明具有外部访问权限的变量
- 为什么在以下代码段中无法访问中的变量值
- 为什么原型需要通过实例访问
- 为什么可以't在对指令的html调用中访问$rootScope
- 为什么我得到“;错误:预期"同时访问字符串
- 为什么我的HTML似乎无法访问我的javascript
- 为什么我不能在 ajax 成功中访问 $(this)
- 为什么我无法访问使用 $provide.provider 和 $injector.get 创建的服务
- 为什么我不能在javascript中访问这个变量
- 为什么我得到“;访问控制允许起源”;当已经设置了头时,通过AJAX下载文件
- 为什么可以在内部函数成员中访问对象引用,而不能在内部属性成员中访问
- 为什么我的firefox扩展javascript不能访问opener窗口,也看不到window.name
- 为什么可以't我通过ID访问这个动态加载的DOM元素(没有iframe)
- 为什么我可以't使用点表示法访问JSON字典元素
- void(0) 返回 'undefined',但允许属性访问.为什么
- 自执行块内的Javascript函数不可访问.为什么
- DOM属性访问:为什么是"elt.class"不工作