gpt4 book ai didi

javascript - 为什么我无法从 onreadystatechange 处理程序内部访问 xhr 对象?

转载 作者:行者123 更新时间:2023-12-03 00:41:26 26 4
gpt4 key购买 nike

编辑:我删除了原始代码,并将其替换为任何人都可以自己运行以重现我的问题的通用代码:

var StripeCheckout = {
configure: function(obj){
obj.token();
}
};

StripeCheckout.configure({
token: function(token) {
var request = new XMLHttpRequest();
request.open('POST', 'http://localhost:3000/process-order');
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
request.onreadystatechange = function() {
debugger; // right here is the problem
};
request.send();
}
});

对我来说,在那个匿名函数中 debugger声明是,request神秘地没有定义,尝试访问它是 ReferenceError 。这真的让我很困惑。

这是奇怪的部分。如果我创建一个在顶层定义的一次性变量,并设置 throwaway = request;创建request后立即对象,然后在 onreadystatechange 内处理程序throwaway已定义,一切正常,即使 request未定义。

我刚刚测试了它,我也可以通过 this 访问它正如预期的那样,在调试器语句处。是什么赋予了?为什么是request没有定义?

最佳答案

引用request是对内部函数周围执行上下文的引用,内部函数是实现闭包一部分的堆分配结构,并且会受到垃圾收集。

如上所述here ,如果没有引用,V8 JavaScript 引擎(Chrome 和 Node.JS 等应用程序使用该引擎来实现 JavaScript)不会创建闭包。 (这是一项优化。)因此,当您打开调试器时,对 request 的引用已丢失,这就是为什么您会得到 ReferenceError而不是undefined 。请注意,Safari 11 中的行为有所不同,它使用 WebKit 中的 JavaScriptCore(而不是 V8)来实现 JavaScript。

如果添加对 request 的引用在内部函数内部,然后 V8 将创建闭包,您将可以在调试器内部访问 in 。

示例

在 Chrome 中运行此代码(或者像我一样在 Opera 中运行,它也使用 V8),您将看到作用域链中列出的闭包。

var StripeCheckout = {
configure: function(obj) {
return obj.token();
}
};

StripeCheckout.configure({
token: function(token) {
var request = new XMLHttpRequest();
request.open('POST', 'https://jsonplaceholder.typicode.com/posts');
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
request.onreadystatechange = function() {
// include the console.log statement
// and everything works as expected.
console.log('req.rs:', request.readyState);
debugger; // right here is the problem
};
request.send();
}
});

Chrome debugger showing closure

注释掉console.log语句,这是对闭包的唯一引用,并且闭包本身消失(使用 V8)。

Closure not present with V8

但是,当您在 Safari 中运行相同的代码(没有引用)时,它使用 WebKit 中的 JavaScriptCore 而不是 V8,并且闭包仍然存在 request已定义,并且调试器按预期工作。

Closure present in Safari

关于javascript - 为什么我无法从 onreadystatechange 处理程序内部访问 xhr 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53448066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com