javascript中的函数通过保持(隐藏)链接到其封闭范围来形成闭包。
当我们有函数(作为变量值)时,是否可以以编程方式访问它?
真正的目标是理论上的,但演示可能是列出闭包的属性。
var x = (function(){
var y = 5;
return function() {
alert(y);
};
})();
//access y here with x somehow
答案 0 :(得分:4)
这是(关闭)目的之一 - 保持信息私密性。由于函数已经被执行,它的范围变量不再可以从外部获得(并且从未有过) - 只有在其范围内执行的函数(仍然)才能访问。
但是你可以通过getter / setter提供访问权限。
您可能需要了解有关闭包的Stuart Langridge's talk。非常值得推荐的还有Douglas Crockfords Explanations。你可以用闭包做很多花哨的东西;)
编辑: 您有几个选项来检查闭包:在webdeveloper控制台中观察对象或(我经常这样做)返回一个调试函数,它将所有私有变量转储到控制台。
答案 1 :(得分:3)
不,除非你揭露它:
var x = function(){
var y = 5;
return {
getY: function(){
return y;
},
setY: function(newY){
y = newY;
}
}
}
x.setY(4);
答案 2 :(得分:2)
您可以编辑提醒功能:
var x = (function(){
var y = 5;
return function() {
alert(y);
};
})();
var oldAlert = alert;
alert = function (x) {
oldAlert(x);
window.y = x;
}
x();
console.log(y); // 5
或者,如果您拥有代码,则可以使用标准的getter和setter。
答案 3 :(得分:0)
如果可以在 prior 脚本标签中执行自己的Javascript,则可以选择附加MutationObserver,等待要监视的脚本标签插入文档中,然后右键单击。插入时,更改其代码,以便暴露您要检查或更改的功能。这是一个示例:
<script>
new MutationObserver((mutations, observer) => {
// Find whether the script tag you want to tamper with exists
// If you can't predictably identify its location,
// you may have to iterate through the mutations' addedNodes
const tamperTarget = document.querySelector('script + script');
if (!tamperTarget) {
return;
}
observer.disconnect();
console.log('Target script getting tampered with');
tamperTarget.textContent = tamperTarget.textContent.replace(
'return function',
'window.y = y; return function'
);
setTimeout(() => {
console.log("Hacked into tamper target's script and found a y of", y);
console.log('Could also have replaced the local y with another value');
});
})
.observe(document.body, { childList: true });
</script>
<script>
console.log('Tamper target script running');
var x = (function(){
var y = 5;
return function() {
alert(y);
};
})();
</script>
这可能不是您要记住的,但是这种方法是破解闭包的极少数方法之一,当页面运行无法更改的代码时,这是一种有用的技术。
如果其他脚本使用的是src
而不是内联代码,则将变得更加困难-您必须获取script标签的文本(可能将请求从另一台服务器上退回以避免CORS问题),然后才能进行所需的替换并插入修补的代码。 (或者,如果您有服务器,则可以让 server 进行文本替换-然后,您所需要做的就是更改插入的脚本标签的src
指向您的服务器而不是默认位置。)