js 中立即执行匿名函数表达式中的 this 指代的是什么

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

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7673129
  • 你也可以参考下这篇文章:js怎样获取元素节点 怎样获取某个元素下的第一个节点 获取相邻的兄弟节点
  • 除此之外, 这篇博客: JS立即执行函数写法及其具体应用中的 JS立即执行函数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    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运算后的值
    

    所以推荐使用以上两种用()包裹的方法

    立即执行函数的应用

    1. 页面的初始化工作(执行完成后销毁,不会占用空间)
    2. 避免污染全局变量
    3. 只执行一次的代码需要变量,将这些临时变量定义成全局变量会非常不好,这时可以将这些变量包裹在立即执行函数中
    4. 立即执行函数会形成一个单独的作用域

    一个典型的例子:

    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 的值不会互相影响)

  • 您还可以看一下 黄菊华老师的微信小程序前端程序设计和JS入门到精通课程中的 微信小程序入门到就业课(全栈课)学习说明【建议看下】小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^