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文档: