关于js中this指向问题的一些学习经验分享

JavaScript中this的指向问题分享

写在前面的说明:
这里就是自己学习记录理解的this指向问题,有些也是有借鉴一些大神文章,如果不全或者错误的请大神指教,理解 谢谢!

这里抛出出一个常见的this指向问题


<div id="box">div</div>
<script>
    var box=document.getElementById('box');
    box.οnclick=function(){
        setTimeout(function(){
            this.style.backgroundColor='red';
        },1000)
    }
</script>
//Chrome下抛出:
//Uncaught TypeError: Cannot set property 'backgroundColor' of undefined at ...

解决办法:定时器中的this指向是window 解决办法 var that=this 这里的this的指向是box

<script>
var box=document.getElementById('box');
box.οnclick=function(){
    //定时器中的this指向是window 解决办法 var that=this 这里的this的指向是box
    var that=this
    setTimeout(function(){
        this.style.backgroundColor='red';
    },1000)
   
}
</script>
正文开始

1.1.全局作用域或者普通函数中 this 指向全局对象 window(全局环境)

//直接打印
console.log(this) //window

//function声明函数
function fn() {console.log(this)}
fn() //window

//function声明函数_这里有个严格模式:
function fn(){
   "use strict"
    console.log(this);
}
fn();//undefined

//function声明函数赋给变量
var fn = function () {console.log(this)}
fn() //window

//自执行函数
(function () {console.log(this)})(); //window

1.2.call()和bind改变this指向

//call()
function fn1(){
     console.log(this.a);
}
fn1.call({a:1});//1 call方法会立即执行,同时 函数主体里的this会立即指向{a:1}这个对象

function fn2(m,n){
    console.log(this.a,m,n);
}
fn2.call({a:1},2,3);//1 2 3
//函数.call会直接调用该函数,并且call的第0个参数就是函数执行的this
// 后面的参数是函数执行的参数


//bind()
function fn(m,n){
    console.log(this.a);
}
var fn1=fn.bind({a:2});//bind函数是返回一个新的函数
var fn2=fn.bind({a:3});
var fn3=fn.bind({a:4});
console.log(fn1)
console.log(fn2)
console.log(fn3)
fn1()//2
fn2()//3
fn3()//4
----这里以上的bind绑定后的新函数 fn 指向的this就是 bind(后面的的对象了)
同时注意一点
绑定过后的fn1函数 如果在绑定bind的指向就是第一次绑定的对象()

//==============================================
function fn(){
    console.log(this);
}
var fn1=fn.bind(1)
fn1()//number:1

2.方法调用中谁调 this 就指谁(事件处理函数)

<div id="oo" οnclick="console.log(this)"></div>
this的指向:<!--this指的是 <div id="oo" οnclick="console.log(this)"></div>-->

<div id="oo" οnclick="(function(){console.log(this)})()"></div>
this的指向:<!--window-->

<div id="box">1111</div>
//对象方法调用
var box= {
  fn: function () {console.log(this)}
}
box.run() // box

//事件绑定
var box=document.getElementById('box');
box.onclick = function () {
  console.log(this) // 事件处理函数中this 该事件右谁触发 就是指的是谁 <div id="box">1111</div>
}
//事件监听
var box= document.querySelector("#box")
box.addEventListener('click', function () {
  console.log(this) //box //<div id="box">1111</div>
})

3.构造函数

//不使用new指向window
function Fn(name) {
  console.log(this) // window
  this.name = name;
}
Fn('pets')
//使用new 构造
function Fn(name) {
  this.name = name
  console.log(this) //fn
  self = this
}
var fn= new Fn('pets')
console.log(self === fn) //true
//这里new改变了this指向,将this由window指向Fn的实例对象fn

function Fn(){
    this.a=1;
    return 1;//如果返回非NaN,那么实例化结果就是返回出对象 
} 
var f=new Fn();
console.log(f);//{a:1}
//===============================================
function Fn1(){
    this.a=1;
    return {}; //如果返回非NaN,那么实例化结果就是返回出对象
} 
var f1=new Fn1();
console.log(f1);//{}  

//=======================================================

4.原型链

var p={
   a:1,
    fn:function(){
        console.log(this.a);
    }
}
var c=Object.create(p);//这里是从母本p上创建一个c,也就是c上有个__proto__指向p
// console.log(c)//{}
// console.log(c.__proto__)//{a: 1, fn: ƒ}
// console.log(c.a)//1
c.fn()//1

5.箭头函数

 var fn=()=>{
     console.log(this);
 }
 fn()//Window

//在箭头函数定义的时候,fn指谁那么箭头函数中this就是指谁
// 这里是是fn()自己的的调用 所以指向window

 box.οnclick=function(){
     setTimeout(()=>{
         this.style.backgroundColor="red";
     },500)
}
//这里的this指向box

//================================================
var fn=()=>{
    console.log(this);
}
var fn9=fn.bind({})
fn9()//window 这里是无法通过bind改变其this的指向的

6.1对象内

var a=1;
var obj={
     a:2,
     fn1:function(){
         console.log(this.a);
     }
 }  
 obj.fn1()//2
 obj.fn1.bind({a:"pets"})()//pets

 //=====================================
 var obj={
     a:1
 }
 var fn=function(){
     console.log(this.a);
 }
 obj.fn=fn;
 obj.fn();//1
 //============================================
 var obj={
     a:1
 }
 var fn=function(){
     console.log(this.a);
 }
 obj.fn=fn;

 var fn1=()=>{
     console.log(this.a);
 }
 obj.fn1=fn1;

 obj.fn()//1
 obj.fn1();//window
 //=========================================
     var a=1;
     var obj={
         a:2,
         o:{
             a:3,
             fn:function(){
                 console.log(this.a);
             }
         }
     }
     obj.o.fn();//3 就近绑定
     var temp=obj.o.fn;
     temp()//1

6.2.对象内函数定义箭头函数

var a=1;
var obj={
    a:2,
    fn1:()=>{
        console.log(this.a);
    },
    fn2:function(){
        console.log(this.a)
    }
}
//箭头函数是谁申明我就更谁跑,
obj.fn1();//1 this的这里指的是window,
//function是谁调用它,他的this指针就是谁,这里是obj进行的调用 所以最后是取了 obj中的a的值
obj.fn2();//2 this的这里指的是obj

6.3.对象内函数返回箭头函数

var a=1;
var obj={
    a:2,
    fn1:function(){
        return function(){
            console.log(this.a);
        }
    },
    fn2:()=>{
        return ()=>{
            console.log(this.a)
        }
    },
    fn3:function(){
        return ()=>{
            console.log(this.a);
        }
    }
}  
var innerFn1=obj.fn1();
innerFn1()// 1 
//箭头函数在哪里出生 this 就指向谁;
var innerFn2=obj.fn2();
innerFn2()//1
var innerFn3=obj.fn3();
innerFn3()//2

后续还有set和get的设置中this的指向…继续学习吧…

–end–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值