js 中立即执行匿名函数表达式中的 this 指代的是什么,
以下给出一个例子,尽可能举出更多例子来说明
var myObject = {
foo: "bar",
func: function () {
var self = this;
console.log(this.foo);
console.log(self.foo);
(function () {
console.log(this.foo);
console.log(self.foo);
})();
},
};
myObject.func();
在 JS 中,立即执行匿名函数表达式是常见的一种模块化组织代码的方式,常常用于避免全局作用域的变量污染和函数命名冲突。在这种模式下,匿名函数会在定义时立刻执行,通常会使用到闭包。那么,在这种模式下,this 指代的到底是什么呢?
在立即执行匿名函数表达式中的 this,实际上是指向全局对象(在浏览器中为 window,在 Node.js 中为 global)。这与函数传入的参数、使用的变量以及函数本身的作用域无关。下面是一些例子,以便更好地理解:
(function() {
console.log(this); // 指向全局对象
})();
(function() {
'use strict';
console.log(this); // 指向 undefined
})();
var obj = {
myMethod: function() {
console.log(this); // 指向全局对象
}
};
(function() {
obj.myMethod(); // 指向全局对象
})();
var obj = {
myMethod: function() {
(function() {
console.log(this) // 指向全局对象
})();
}
};
obj.myMethod();
var obj = {
myMethod: function() {
(function() {
'use strict';
console.log(this) // 指向 undefined
})();
}
};
obj.myMethod();
在上述例子中,this 都指向全局对象(window 或 global)。
需要注意的是,在使用 this 时需要注意其指向,因为不同的上下文中 this 的指向是不一样的。如果是想绑定特定的上下文对象,可以使用 call、apply、bind 等函数来指定 this 指向。
总之,在立即执行匿名函数表达式中,this 指代的是全局对象,它不受函数内部上下文的影响。
指代上下文中的this对象
function foo() {
console.log(this);
}
foo(); // 输出 "window"
这个例子是将 this 关键字绑定到上下文中的 window 对象上。所以在调用 foo 函数时,它会在控制台中输出 window
代码中匿名函数表达式中的 this 指代的是window
不知道你这个问题是否已经解决, 如果还没有解决的话:JS立即执行函数形式与具体应用
首先分清函数声明和函数表达式
//函数声明:
function a() {
//.....
}
//函数表达式:
var b = function(){
//.....
}
注意:函数声明在预编译时,会被提升到最顶部
函数表达式不会被提升
立即执行函数的写法
当一对圆括号跟在函数表达式之后,该函数将成为立即执行函数
立即执行函数的两种常用写法:
(function (){
//执行代码
}());
(function (){
//执行代码
})();
//基本原理可以理解为:
var abc=function(){
console.log(123);
}
abc();
立即函数的实参与形参位置
(function ( a, b, c){
console.log(a + b + c);
})( 1, 2, 3);
//可以理解为:
var abc=function( a, b, c){
console.log(123);
}
abc( 1, 2, 3);
! + - = ()等运算符都能将函数声明或匿名函数转换为函数表达式
例如立即执行函数的其他写法:
+ function a(b){
nsole.log(b);
}(123) //打印出123
- function a(b){
console.log(b);
}(123) //打印出123
! function a(b){
console.log(b);
}(123) //打印出123
但是当立即执行函数有返回值时,! + -这些符号也会和返回值进行运算,从而出现不必要的麻烦,例如:
var a=!function(){
return 123;
}()
console.log(a); //打印出false,因为a接受的为!123运算后的值
所以推荐使用以上两种用()包裹的方法
立即执行函数的应用
一个典型的例子:
function demo(){
var arr=[];
for(var i = 0; i < 10; i++){
arr[i]=function(){
document.write(i+" ");
}
}
return arr;
}
//循环执行函数,并打印值
var myarr = demo();
for(var k = 0; k < 10; k++){
myarr[k]();
}
最后输出十个10,并不是0到9
因为在该段代码中,生成了十对一的闭包,在匿名函数中的 i 并不会在赋值过程中变现(替换为数字)
arr数组的所有函数拿到的均为demo产生的执行期上下文对象(AO),所以他们共用一个 i
当循环触发时,在向demo中的AO寻找 i 时,i 已经变为10,所以全部打印10
function demo(){
var arr=[];
for(var i = 0; i < 10; i++){
//通过立即执行函数,生成十对十的闭包
//每个函数拿到的都是立即执行函数的执行期上下文(AO),所j不同
(function(j){
arr[j]=function(){
document.write(j + " ");
}
}(i));
}
return arr;
}
var myarr = demo();
for(var k = 0; k < 10; k++){
myarr[k]();
}
通过立即执行函数解决了这一问题,每个匿名函数都在立即执行函数中,即每个函数都有各自的立即执行函数的AO对象
所以每个函数所打印的 j 即为各自AO对象中的 j(因为立即执行函数运行后会被销毁,所以每次循环都会创建新的AO对象,各自 j 的值不会互相影响)