javascript 中的函数通过保持与其封闭范围的(隐藏)链接来形成闭包。
当我们拥有函数(作为变量值)时,是否可以通过编程方式访问它?
真正的目标是理论上的,但演示可能是列出闭包的属性。
var x = (function(){
var y = 5;
return function() {
alert(y);
};
})();
//access y here with x somehow
javascript 中的函数通过保持与其封闭范围的(隐藏)链接来形成闭包。
当我们拥有函数(作为变量值)时,是否可以通过编程方式访问它?
真正的目标是理论上的,但演示可能是列出闭包的属性。
var x = (function(){
var y = 5;
return function() {
alert(y);
};
})();
//access y here with x somehow
这是关闭的(一个)目的 - 保持信息的私密性。由于该函数已经被执行,它的作用域变量不再可以从外部获得(并且从来没有)——只有在它的作用域中执行的函数(仍然)可以访问。
但是,您可以通过 getter/setter 授予访问权限。
你可能想看看Stuart Langridge关于闭包的讨论。Douglas Crockfords Explanations 也非常值得推荐。你可以用闭包做很多花哨的东西;)
编辑:您有几个选项来检查闭包:在 webdeveloper 控制台中观察对象,或者(就像我经常做的那样)返回一个调试函数,它将所有私有变量转储到控制台。
不,除非你公开它:
var x = function(){
var y = 5;
return {
getY: function(){
return y;
},
setY: function(newY){
y = newY;
}
}
}
x.setY(4);
您可以编辑警报功能:
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。
如果您在前端环境中,并且可以在先前的脚本标签中执行自己的 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>
MutationObserver 看到标签时,调整它或用新的脚本标签替换它,该标签textContent
是原始脚本内容加上您的修改。为了获得原始内容,<script>
在进行所需的替换和插入补丁代码。(或者,如果你有一个服务器,你可以让服务器进行文本替换 - 然后,你需要做的就是src
将插入的脚本标记更改为指向你的服务器而不是默认位置。)