gpt4 book ai didi

javascript - javascript 闭包和作用域问题

转载 作者:行者123 更新时间:2023-11-30 06:34:56 25 4
gpt4 key购买 nike

我有一个名为 writeMessage 的函数。 writeMessage 调用 ajax 请求以获取本地化内容。一旦从 ajax 请求返回内容,它也会在“n”秒后淡出消息。所以一切正常,我已经测试了很多调用,但是,我觉得它过于复杂,因为在处理 javascript 闭包语句时我不完全理解变量的范围。任何人都可以告诉我是否在这里跳过太多的圈来完成以下任务。

函数getTextResource接受参数,(字符串,字符串,对象,函数)

  • 'function' 参数是一个回调,一旦 ajax请求已完成。
  • “object”参数是一个参数对象,包含所有有关如何以及在何处编写消息的详细信息。
  • 'string' 和 'string' 参数被传递到 ajax请求。

在 getTextResource 中,我正在调用一个 ajax 方法,将“object”参数作为上下文以及原始默认文本和回调函数传递ajax 请求完成后,我现在通过上下文调用回调函数,将服务调用的结果和参数传递给它。

我是否需要继续传递上下文,或者如果再次调用该函数,传递给 getTextResoruce 的所有内容是否都不会被分配不同的值?

function writeMessage(args) {
var d = $('<div></div>');

getTextResource(args.resourceId, args.message, { args: args, messageElement: d },
function (text, context) {
var args = context.args;
var d = context.messageElement;

d.empty();
d.append(text);

args.element.append(d);

if (args.fadeTimeOut > 0)
setTimeout(function () {
d.fadeOut('slow', function () {
$(this).remove();
});
}, args.fadeTimeOut);
}
);
}

var getTextResource = function (resourceId, defaultText, context, cb) {
resourceId = resourceId + '';
defaultText = defaultText + '';

if (resourceId == '') resourceId = defaultText;
if (defaultText == '') defaultText = resourceId;

try{
var request = $.ajax({
type: 'GET',
url: 'http://localhost/EaiCCM/api/' + BusinessScope.Version + '/' + BusinessScope.CampaignSegment + '/TextResource',//?' + qs,
data: {ResourceId: resourceId, DefaultText: defaultText},
cache: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
context: { defaultText: defaultText, context: context, cb: cb }
});

request.done(function (result) {
var txt = this.defaultText;
try {
if ($.isPlainObject(result))
txt = result.Detail;
}
catch (e) {
}
finally {
if (typeof this.cb == 'function')
this.cb(txt, this.context);
}
});

request.fail(function (jqXHR, textStatus, context) {
if (typeof this.cb == 'function')
this.cb(this.defaultText, this.context);
});
}
catch (e) {
if (typeof cb == 'function')
cb(defaultText, context);
}
};

最佳答案

不,如果您在 writeMessage 的范围内构造它,则不需要用于回调的 context 对象。 (范围是函数的每次调用的局部范围。)

这个:

    function (text, context) {
var args = context.args;
var d = context.messageElement;

可以很容易地:

    function (text) {

request.done可以读取:

    request.done(function (result) {
var txt = defaultText;
try {
if ($.isPlainObject(result))
txt = result.Detail;
}
catch (e) {
}
finally {
if (typeof cb == 'function')
cb(txt);
}
});

参数的范围仅限于它们作为参数的函数的每次调用。 var 变量的作用域是调用 var 语句上方的第一个 function范围仅持续到关闭该函数的大括号。

因此,在这段代码中:

function writeMessage(args) {
var d = $('<div></div>');
var rid = args.resourceId;

var cb = function (text) {
var exampleVar = text.toUpper();
d.textContent = exampleVar + rid;
}

getTextResource(rid+'-san', 'foo', cb)
getTextResource(rid+'-chan', 'bar', cb)
}

function getTextResource(resourceId,defaultText,cb) {
// for simplicity's sake let's just simulate a default scenario

// Note that the `resourceId` passed to `getTextResource`
// is in no way passed to the callback here

cb(defaultText);
}
  • argsridd 对于 writeMessage 的每次调用都是本地的。
  • textexampleVar 对于回调 cb 的每次调用都是本地的。
  • resourceIddefaultText 对于 getTextResource 的每次调用都是本地的。
  • cb是我们在writeMessage中构造的回调,也是我们在getTextResource中传入的回调。尽管它们具有相同的名称,但不同的作用域意味着它们实际上被视为两个不同的变量。 (如果这令人困惑,请参阅下面的类比。)
  • getTextResource调用'bar'回调时,它会修改与调用回调时相同的d 'foo',因为回调中使用的 d 对构造它的 writeMessage 是本地的。
  • dtextContent 设置的 exampleVar 的值在每次调用中都不同,因为它是本地的回调。
  • exampleVar 的值不会以额外的'-san''-chan' 结尾,因为它们附加到 getTextResource 范围内的 resourceId,这对 writeMessage 范围是不可见的(其中变量被称为 rid 而不是 resourceId 无论如何)。

不同作用域同名变量的类比

变量名称在不同上下文中指代不同的值,例如“Bob”在 Bob's Burgers 中与在 Bob the Builder 中的含义不同。但是,“Bob”在某些情况下可能指的是在其原始上下文中也被称为“Bob”的东西,例如 Archer 第 4 季的第一集中,Sterling 被称为“Bob” "并在 "Bob's Burgers"工作(引用 H. Jon Benjamin 为两个 Angular 色配音)。你可以说这是一个巧合,“真正的”Bob's Burgers “Bob”存在于 Archer 世界的其他地方,但不管他是不是同一个“Bob”这两个上下文与他从 Archer 的一个场景到下一个场景都是同一个“Bob”无关。

关于javascript - javascript 闭包和作用域问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15177073/

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