heal

导航

 

透彻认识function的this在不同调用环境下的指向

  • 事件调用环境

    谁触发事件,函数里面的this指向的就是谁

例:.html
   <div class="box"></div>
   <script>
         let box = document.querySelector('.box');
         box.onclick = move;
         function move(){
               this.style.left = '100px';
         }
         console.log(this);
   </script>
   结果:window
   新建this.js
   console.log(this);
   结果:node this.js
      {}

全局修改this.js
   修改this.js
   console.log(this === module.exports);
   结果:node this.js
        true
  • 函数内部
    【this最终指向的是调用它的对象】

    普通函数直接调用与window调用
    对象中的函数直接调用与window调用

		例:.html
		<div class="box"></div>
		<script>
		      let box = document.querySelector('.box');
		      box.onclick = move;
		      function move(){
		            this.style.left = '100px';
		      }
		      move();//window 严格模式下 undefined 要使用winodw.move()
		</script>

【函数被多层对象所包含,如果函数被最外层对象调用,this指向的也只是它上一级的对象】

   <script>
    var obj ={
         a:10,
         b:function(){
               console.log(this);
         }
   }
   obj.b();// {a:10,b:f}
   window.obj.b();// {a:10,b:f}

   </script>

   <script>
    var obj ={
         a:10,
         b:{
            fn:function(){
               console.log(this);//声明时,this 没有任何意义
         }
         }
   }

   window.obj.b.fn();// {fn:f}

   </script>

多层对象中的函数的this指向
对象中的函数被赋值给另一个变量

  <script>
    var obj ={
         a:10,
         b:{
            fn:function(){
               console.log(this);
         	 }
         }
   }

   var abc = obj.b.fn();
   abc(); //this 指向 window


   </script>

【构造函数中的this指向的是实例对象】

构造函数中的this指向
new运算符的作用

 <script>
	 function fn(){
	   this.num = 10;
	   //console.log(this.num);
	 }

	 fn.num = 20 ;
	 fn.prototype.num = 30;
	 fn.prototype.method = function(){
	   console.log(this.num)
	 }

	 var prototype = fn.prototype;
	 var method = prototype.method;

	 new fn().method();// 10

	 prototype.method();//30
	 // 等同于 var obj={} obj.x=10 obj.fn= function(){ console.log(this.x)}
	 // 等同于 
	    var obj={
		 x:10,
		 fn: function(){ 
		 	console.log(this.x)
		 }
	    } 

	 method();// undfined

	 var obj = new fn();
	 console.log(obj.num) //10
	 /*
	 1、调用函数
	 2、自动创建一个对象(隐式调用) var obj = {}
	 3、把创建出来的对象和this进行绑定 var this = {}
	 4、构造函数没有返回值,隐式返回this对象
	 */

</script>

【如果构造函数中有return 如果return的值是对象,this指向返回的对象 如果不是对象,则this指向保持原来的规则 return null(null是对象)比较特殊 返回的是this指向保持原来的规则】

<script>
	function fn() {
		this.num = 10;
		return '';
	}
	var obj = new fn();
	console.log(obj.num);//10
	</script>

	<script>
	function fn() {
		this.num = 10;
		return 1;
	}
	var obj = new fn();
	console.log(obj.num);//10
	</script>

	<script>
	function fn() {
		this.num = 10;
		return {};
	}
	var obj = new fn();
	console.log(obj.num);//undifined
	</script>
	<script>
	function fn() {
		this.num = 10;
		return {
		num:20
		};
	}
	var obj = new fn();
	console.log(obj.num);//20
	</script>

	<script>
	function fn() {
		this.num = 10;
		return null;
	}
	var obj = new fn();
	console.log(obj.num);//10
</script>
  • 了解箭头函数中的this指向的特殊性

    箭头函数本身是没有this和arguments的,在箭头函数中引用this实际上调用的是定义的是上一层作用域的this。
    上一层作用域,因为对象不能形成对立的作用域的

     var obj = {
     	fn:function(){ //普通函数
     	 console.log(this); 
     	}
     }
     obj.fn(); //this指向 obj {fn:f}

     var obj = {
     	fn:()=>{ 
     	 console.log(this); 
     	}
     }
     obj.fn()//this指向 window

问题引出
例:.html
   <div class="box"></div>
   <script>
         let box = document.querySelector('.box');
         box.onclick = move;
         function move(){
            setTimeout(function(){
             this.style.left = '100px';//this  指向window
             },1000);
              
         }
         console.log(this);
   </script>
解决:
   <script>
         let box = document.querySelector('.box');
         box.onclick = move;
         function move(){
            setTimeout(() => {
             this.style.left = '100px';
             },1000);
              
         }
         console.log(this);
   </script>
老的方法解决:
   <script>
         let box = document.querySelector('.box');
         box.onclick = move;
        
         function move(){
            var _this = this;
            setTimeout(function(){
             _this.style.left = '100px';
             },1000);
              
         }
         console.log(this);
   </script>
  • 掌握如何改变this指向
    <div class="box"></div>
	<script>
	 let box = document.querySelector('.box'),a,b,c;
	 var obj = {
	      	fn:()=>{ 
	      	 console.log(this);  //this 定义时就决定好了 指向 window
	      	}
	      }
	      obj.fn.call(box);  // call 无效



	  var obj = {
	      	fn:function(){ 
	      	 console.log(this);  //this 定义时就决定好了 指向 window
	      	}
	      }
	      obj.fn.call(box,a,b,c);  // <div class="box"></div>


	      obj.fn.apply(box,[a,b,c]);


	      obj.fn.bin(box);//只是绑定 要执行需要加括号 如:obj.fn.bin(box)()
	      // call bind 参数一样 apply 传数组
	</script>
posted on 2020-10-28 14:44  heal  阅读(90)  评论(0)    收藏  举报