Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正在访问回调函数中的变量。。。什么_Javascript_Jquery - Fatal编程技术网

Javascript 正在访问回调函数中的变量。。。什么

Javascript 正在访问回调函数中的变量。。。什么,javascript,jquery,Javascript,Jquery,我已经通过了大量的帖子,终于得到了我所需要的,这要归功于: $("a.foo").click(function(){ var that = this; jPrompt("Type something:","","", function(r) { $(that).text(r); } } 从以下方面: 我想知道是否有人可以详细说明这里到底发生了什么,为什么不重新分配就无法使用?我应该阅读哪些核心信息?据我所知,这可能与闭包有关。。。这就是我在四处搜索时遇

我已经通过了大量的帖子,终于得到了我所需要的,这要归功于:

$("a.foo").click(function(){
    var that = this;
    jPrompt("Type something:","","", function(r) {
        $(that).text(r);
    }
}
从以下方面:

我想知道是否有人可以详细说明这里到底发生了什么,为什么不重新分配就无法使用?我应该阅读哪些核心信息?据我所知,这可能与闭包有关。。。这就是我在四处搜索时遇到的大部分情况。准确吗

在我的例子中,我希望执行一些代码,然后在ajax请求完成后重定向。在回调函数中,我运行$this.attrref,该函数返回未定义。

这是由javascript根据调用函数的方式分配的。因此,当jPrompt调用回调时,jPrompt函数决定回调中的值

因此,除非jPrompt通过您传入的某个参数特意为它保留相同的值,否则它可能会有不同的值。因此,您可以将其保存起来,以便在回调中进行访问。这是javacscript回调中非常常见的设计模式

供参考,分配的一些方式:

obj.method-此in方法将设置为obj func.callobj-func中的此项将设置为obj func-这将在func模式下设置为window,或在strict模式下设置为undefined 这是由javascript根据调用函数的方式分配的。因此,当jPrompt调用回调时,jPrompt函数决定回调中的值

因此,除非jPrompt通过您传入的某个参数特意为它保留相同的值,否则它可能会有不同的值。因此,您可以将其保存起来,以便在回调中进行访问。这是javacscript回调中非常常见的设计模式

供参考,分配的一些方式:

obj.method-此in方法将设置为obj func.callobj-func中的此项将设置为obj func-这将在func模式下设置为window,或在strict模式下设置为undefined
问题中的代码中添加了一些注释:

$("a.foo").click(function(){
    var that = this; //`this` holds the a object clicked.  now so does `that`! 
    jPrompt("Type something:","","", function(r) { 
        //even if `this` has a different value here, `that` still holds the a object clicked
        $(that).text(r);
    }
}
这是你经常会发现自己在类似的情况下做的事情。这是上下文相关的,您通常需要在一个上下文中保留该值,并在另一个上下文中使用它

引自ECMAScript规范:

10.1.7本条 有一个与此值关联的值 每个活动执行上下文。这个 此值取决于调用方和 正在执行的代码类型,并且 确定控件何时进入 执行上下文

希望这能回答你的问题。您还要求提供进一步阅读的资源。请浏览:


这些家伙提供了优秀的文档,既详细又准确,不像其他流行的参考资料来源,它们通常在谷歌搜索中排在第一位-w3cshools.com我在想你

问题代码中添加了一些注释:

$("a.foo").click(function(){
    var that = this; //`this` holds the a object clicked.  now so does `that`! 
    jPrompt("Type something:","","", function(r) { 
        //even if `this` has a different value here, `that` still holds the a object clicked
        $(that).text(r);
    }
}
这是你经常会发现自己在类似的情况下做的事情。这是上下文相关的,您通常需要在一个上下文中保留该值,并在另一个上下文中使用它

引自ECMAScript规范:

10.1.7本条 有一个与此值关联的值 每个活动执行上下文。这个 此值取决于调用方和 正在执行的代码类型,并且 确定控件何时进入 执行上下文

希望这能回答你的问题。您还要求提供进一步阅读的资源。请浏览:

这些家伙提供了优秀的文档,既详细又准确,不像其他流行的参考资料来源,它们通常在谷歌搜索中排在第一位-w3cshools.com我在想你

这个词的意思会随着你所处的位置而变化。click事件处理程序中的this表示传递给jPrompt函数的回调中的this以外的内容

无论如何,您不需要重新分配它,因为传递到处理程序中的事件对象将引用currentTarget:

这句话的意思会随着你所处的位置而变化。click事件处理程序中的this表示传递给jPrompt函数的回调中的this以外的内容

无论如何,您不需要重新分配它,因为传递到处理程序中的事件对象将引用currentTarget:

这方面的简要概述 这在JavaScript中是动态确定范围的。它的行为不同于所有其他词汇范围的变量。根据调用函数的方式,其他变量没有不同的绑定;它们的范围来自它们在脚本中出现的位置。但是,这会有不同的行为,并且会有不同的绑定,这并不取决于它在脚本中的显示位置,而是取决于它的调用方式。因此,它可能是一个来源 学习该语言的人可能会感到困惑,但要成为一名熟练的JavaScript开发人员,掌握它是必要的

由于这是动态绑定的,因此有几种方法可以根据调用函数的方式更改其值

例子 当您在JavaScript中执行一个函数时,默认情况下这是一个窗口

可以通过多种方式更改此值。一种方法是将函数作为对象的方法调用:

var x = {
    foo: function() {
        console.log(this);
    }
};
x.foo(); // => This time it's the x object.
另一种方法是使用call或apply来告诉函数在特定对象的上下文中执行

function foo() {
    console.log(this);
}
foo.call(x); // => x object again
foo.apply(x); // => x object as well
如果调用或应用null或undefined,则默认行为将再次发生:函数将在以下窗口的上下文中执行:

但是,请注意,在ECMAScript 5严格模式下,这并不默认为窗口:

(function() {

    'use strict';

    function foo() {
        console.log(this);
    }

    foo(); // => undefined
    foo.call(null); // => null
    foo.apply(undefined); // => undefined

})();
您还可以通过使用bind在调用函数之前将其绑定到对象来设置此选项:

function foo() {
    console.log(this);
}

var bar = {
    baz: 'some property'
};

var foobar = foo.bind(bar);

foobar(); // => calls foo with bar as this
行将的父亲:懒散地捆绑/不修剪这个 更进一步说,您有时可能希望使用作用于this的函数,并允许this值作为函数的第一个参数传入。这对数组方法(如forEach)非常有用。例如,假设您处理的对象类似于数组,但实际上不是数组

var arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    'length': 3
};
如果要使用forEach迭代此对象,可以使用call:

但是,另一个选项是创建可直接在对象上调用的forEach函数:

var forEach = Function.prototype.call.bind(Array.prototype.forEach);
现在,您可以随时使用此函数来迭代类似数组的对象:

forEach(arrayLike, function(item) {
    console.log(item);
});
// Logs: a, b, c
有时这种方法被称为“不修剪”。但是,我更喜欢创建一个函数,它可以生成这些未传输的函数,并将其称为延迟绑定

var lazyBind = Function.prototype.bind.bind(Function.prototype.call);

var forEach = lazyBind(Array.prototype.forEach);
var slice = lazyBind(Array.prototype.slice);
var map = lazyBind(Array.prototype.map);

forEach(arrayLike, function(u) {
    console.log(u);
});
// Logs: a, b, c

var realArray = slice(arrayLike);
// Converts arrayLike into a real array

forEach(
    map(arrayLike, function(u) {
        return u + 'Q';
    }),
    function(u) {
        console.log(u);
    }
);
// Logs: aQ, bQ, cQ
这项技术有一个非常棒的地方,那就是它对于创建安全的JavaScript非常有用,如果您不想让页面上的其他脚本窥探您的内部变量,这将非常有用。不过,这是一种非常先进的元编程技术,在日常JavaScript中看不到它。

这是一个简短的概述 这在JavaScript中是动态确定范围的。它的行为不同于所有其他词汇范围的变量。根据调用函数的方式,其他变量没有不同的绑定;它们的范围来自它们在脚本中出现的位置。但是,这会有不同的行为,并且会有不同的绑定,这并不取决于它在脚本中的显示位置,而是取决于它的调用方式。因此,对于学习该语言的人来说,它可能是一个混乱的来源,但是掌握它对于成为一名熟练的JavaScript开发人员是必要的

由于这是动态绑定的,因此有几种方法可以根据调用函数的方式更改其值

例子 当您在JavaScript中执行一个函数时,默认情况下这是一个窗口

可以通过多种方式更改此值。一种方法是将函数作为对象的方法调用:

var x = {
    foo: function() {
        console.log(this);
    }
};
x.foo(); // => This time it's the x object.
另一种方法是使用call或apply来告诉函数在特定对象的上下文中执行

function foo() {
    console.log(this);
}
foo.call(x); // => x object again
foo.apply(x); // => x object as well
如果调用或应用null或undefined,则默认行为将再次发生:函数将在以下窗口的上下文中执行:

但是,请注意,在ECMAScript 5严格模式下,这并不默认为窗口:

(function() {

    'use strict';

    function foo() {
        console.log(this);
    }

    foo(); // => undefined
    foo.call(null); // => null
    foo.apply(undefined); // => undefined

})();
您还可以通过使用bind在调用函数之前将其绑定到对象来设置此选项:

function foo() {
    console.log(this);
}

var bar = {
    baz: 'some property'
};

var foobar = foo.bind(bar);

foobar(); // => calls foo with bar as this
行将的父亲:懒散地捆绑/不修剪这个 更进一步说,您有时可能希望使用作用于this的函数,并允许this值作为函数的第一个参数传入。这对数组方法(如forEach)非常有用。例如,假设您处理的对象类似于数组,但实际上不是数组

var arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    'length': 3
};
如果要使用forEach迭代此对象,可以使用call:

但是,另一个选项是创建可直接在对象上调用的forEach函数:

var forEach = Function.prototype.call.bind(Array.prototype.forEach);
现在,您可以随时使用此函数来迭代类似数组的对象:

forEach(arrayLike, function(item) {
    console.log(item);
});
// Logs: a, b, c
有时这种方法被称为“不修剪”。但是,我更喜欢创建一个函数,它可以生成这些未传输的函数,并将其称为延迟绑定

var lazyBind = Function.prototype.bind.bind(Function.prototype.call);

var forEach = lazyBind(Array.prototype.forEach);
var slice = lazyBind(Array.prototype.slice);
var map = lazyBind(Array.prototype.map);

forEach(arrayLike, function(u) {
    console.log(u);
});
// Logs: a, b, c

var realArray = slice(arrayLike);
// Converts arrayLike into a real array

forEach(
    map(arrayLike, function(u) {
        return u + 'Q';
    }),
    function(u) {
        console.log(u);
    }
);
// Logs: aQ, bQ, cQ

这项技术有一个非常棒的地方,那就是它对于创建安全的JavaScript非常有用,如果您不想让页面上的其他脚本窥探您的内部变量,这将非常有用。不过,这是一种非常先进的元编程技术,在日常JavaScript中看不到它。

查找词法范围和动态范围。JS中的大多数变量都是词汇作用域,但这是动态作用域。您应该阅读MDN文档:查找词汇作用域和动态作用域。JS中的大多数变量都是词汇范围,但这是动态范围。您应该阅读MDN文档: