JS中的this的指向

JS中的this的指向是个令人头疼的问题,看了好多博客,自己总结一下大家也看一下:

什么是this?

this是JavaScript语言的一个关键字,它是函数运行时自动生成的一个内部对象,只能在函数内部调用

最重要的一句话:this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁最终调用函数,this就指向谁。

情况一:所有在全局作用域中定义的变量和函数都是window对象的属性和方法,下面两种代码效果是一样的,window对象调用a(),所以this就指向window对象。

function a(){
    var user = "cat";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();//this-->window,全局作用域下调用
function a(){
    var user = "追梦子";
    console.log(this.user); //undefined
    console.log(this); //Window
}
window.a();//this-->window,全局作用域下调用

情况二:o对象调用fn(),所以this指向o对象,这里需要强调一点:我们创建的o对象其实是window对象的属性,所以可以通过window对象来引用o对象。

var o = {
    user:"追梦子",
    fn:function(){
        console.log(this.user); //追梦子
    }
}
window.o.fn();//this-->o,o调用

情况三:如果存在对象的嵌套,那么this对应的函数如果被上一级的对象所调用,那么this指向的就是上一级的对象。

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();//this-->b,b调用

情况四:

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();//this-->window

虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window。

情况五:函数作为构造函数,用new 关键字调用时,this指向new出来的对象

function func(){
    console.log(this);
}
var obj = new func();this-->obj

情况六:函数作为window内置函数(setInterval setTimeout等)的回调函数使用,this指向window

function func() {
    console.log(this);
}
setTimeout(func,1000);//this-->window

情况七:全局函数在严格模式下this默认指向undefined

function foo() {
    'use strict';
    console.log(this);
}
foo();//this-->undefined

情况八:箭头函数没有自己的this,不绑定this,它的this是继承而来的,指向定义时所在的对象

var obj = {  
   say: function () {  
     setTimeout(() => {  
       console.log(this);// this继承自obj,故this指向obj    
     });  
   }  
 }  
 obj.say();
var obj = {
    say: function () {
        var f1 = () => {
            console.log(this); // this指向定义时所在对象obj
            setTimeout(() => {
                console.log(this); // this继承自f1
            },1000)
        }
        f1();
    }
}
obj.say()
var obj = {
    say: function () {
        var f1 = function () {
            console.log(this); // this指向window, f1调用时,没有宿主对象,默认是window
            setTimeout(() => {
                console.log(this); // this继承自f1,故指向window
            })
        };
        f1();
    }
}
obj.say()

情况九:

function fruits() {}
 
fruits.prototype = {
    color: "red",
    say: function() {
        console.log("My color is " + this.color);
    }
}
 
var apple = new fruits;
apple.say();    //My color is red

但是如果我们有一个对象banana= {color : "yellow"} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:

banana = {
    color: "yellow"
}
apple.say.call(banana);     //My color is yellow
apple.say.apply(banana);    //My color is yellow

所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值