JavaScript浅谈this的指向

this的指向

关于this的指向,除去原型链以及call、apply、bind这些我还没学懂的之外,主要有以下几点:

1. 全局环境下
2. 函数内
3. 对象内(方法内)
4. 箭头函数
5. 构造函数

一、全局环境下的this指向

全局作用域下,this始终指向全局对象window

console.log(this);  //window
//相当于:
window.console.log(this);   //这是window下的console方法

console.log()的完整写法是window.console.log(),window可以被省略所以在这里this是指向了window

二、函数内的this指向

普通函数内的this分为两种情况,严格模式下和非严格模式下
1. 严格模式 — ‘use strict’
对代码的的调用必须严格的写出被调用的函数的对象,不可以有省略或者说简写。

function test(){
    'use strict'
    console.log(this);
}
test();  		//undefined
window.test();  //window

this不知道指向谁,所以打印undefined
虽在严格模式,但window调用test函数,所以指向window

2. 正常模式

function test(){
    console.log(this);
}
test();
window.test();

在正常模式中,直接调用test()和window.test()性质一样,所以this都指向window

三、对象中(方法中)的this指向

对象内部方法的this指向调用这些方法的对象,就是谁调用就指向谁(有点暴躁哈∩_∩ ),在这里分为两种情况:

1. 单层对象:

var obj = {
    name : '张三',
    skillone : function(){
        name : "李四",
        console.log(this.name);
    }
}
obj.skillone();    //张三

此时this指向obj,因为skill是被obj调用的。

2. 多层对象(对象里还有对象)

var obj = {
    name : '张三',
    skillone : function(){
        name : "李四",
        console.log(this.name);
    },
    xobj : {
        name : "王五",
        skilltwo : function(){
            name : "张六",
            console.log(this.name);
        }
    }
}
obj.skillone();    		//张三
obj.xobj.skilltwo();    //王五

此时因为在调用skilltwo()时的顺序为obj.xobj.skilltwo,所以skilltwo是被xobj调用,所以此时this指向xobj

3. 小结一下
a.函数的定义位置不影响其this指向,this指向只和调用函数的对象有关。
b.多层嵌套的对象,内部方法的this指向离被调用函数最近的对象

四、箭头函数中的this

在谈讨this的话题中,箭头函数是个例外,他没有this,是真的没有this!,但是为什么要在这里提他呢,是因为箭头函数比较努力,会自己寻找this并且绑定,他会一级一级的向上寻找,直到寻找到this的指向!换句话说:它会绑定最近的非箭头函数作用域中的this。首先从它的父级作用域找,如果父级作用域还是箭头函数,就再往上找,直到找到。

var show = () => {
    console.log(this);
}

var obj = {
    show : () => {
        console.log(this);
    }
}
window.obj.show();

//----------
show();     		//window
window.show();      //window
obj.show();     	//window
window.obj.show();  //window

1. 在第一个函数中,自身是箭头函数,没有this,所以向上寻找:window.show(),所以绑定在window上
2. 在后面的对象中,obj是对象不是箭头函数,所以他寻找到这里就结束了,但是此时的obj被window调用,所以箭头函数刚刚绑定的this指向了window。

五、构造函数中的this

在构造函数中的this指向实例化的对象
但是,在JS中是没有的,而构造函数是个函数,this指向的永远是个对象,如果不搞点小动作,this就算踏破天也指不到构造函数里面去。下面我们就来浅谈一下所谓小动作是什么。
1. 构造函数在写法上首字母大写(区分普通函数,没人定义,只是约定俗成而已)
2. 构造函数被调用时必须用new,这也是区分普通函数的根本区别,那么new创建对象时都干了些什么?

一、 创建一个Object对象实例;
二、 将构造函数的执行对象赋给新生成的对象的这个实例;
三、执行构造函数中的代码;
四、返回新生成的对象实例;

function Gzfun(a,b,c){
    this.name = a;
    this.age = b;
    this.sex = c;
}
var ren = new Gzfun('zhangsan',18,'nan')
console.log(ren);       //Gzfun {name: 'zhangsan', age: 18, sex: 'nan'}
console.log(ren.name);  //zhangsan
console.log(ren.a);     //undefined

new的ren调用GZfun中的name可以得到传入的nama:zhangsan,可以得出构造函数中的this指向构造函数下创建的实例

function GZfun(){
    this.name = 'wangshi';
    var age = 22;
    window.age = 22;
}
var ren = new GZfun();
console.log(ren.name);      //Tiny Colder;
console.log(ren.age);       //undefined;
console.log(window.age);    //22;

小结:在构造函数中,this指向new操作符实例化出来的对象

六、几种容易出错的this指向:

1.定时器:

定时器里的函数是回调函数,所有的回调函数中的this都是指向window,因为this指向引用正在调用当前方法的"."前的对象。当没有明确的执行时的当前对象时,this指向全局对象window。

setTimeout(function(){
    console.log(this)     //Window
},5000) 

2.自调用函数(立即执行的函数)

说白了还是普通函数,在前面提到的严格模式中是undefined;非严格模式指向window

//严格模式
(function(){
    'use strict'
    console.log(this)   //undefined
})();
//非严格模式
(function(){
    console.log(this)   //window
})();

3.绑定事件方法中的this

// javascript
var  anniu = document.querySelector('button');
btn.onclick = function() {
    console.log(this)   //指向<button>按钮</button>这个元素
}

总结:

1. 全局环境下的this

  • 全局作用域下,this始终指向全局对象window

2. 普通函数中的this

  • 在非严格模式中,this指向window;
  • 在严格模式中,this指向undefined;

3.对象中(方法中)的this

  • 对象内部方法的this指向调用这些方法的对象
  • 函数的定义位置不影响其this指向,this指向只和调用函数的对象有关。
  • 多层嵌套的对象,内部方法的this指向离被调用函数最近的对象
  • 总之就是所调用,指向谁

4.箭头函数中的this

  • 箭头函数没有this
  • 他的this是绑定最近的非箭头函数作用域中的this
  • 构造函数中箭头函数的作用域是这个构造函数,所以this指向的是这个构造函数实例出来的新的对象

5.构造函数中的this

  • 构造函数中的this指向构造函数下创建的实例。

6.因为本人才疏识浅,写的也不太好,对原型链中的this不太了解,以及call、apply、bind更改this的指向的知识还不够了解,以后再补上这些内容,希望有大佬出手指点,文章有些是引用:大佬1 大佬2的东西。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在这放一个div

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值