javascript中的this指向问题(面试高频考点)

js 中 this 的指向归类如下(总共有五种情况,全都是在严格模式下 , 不管哪种情况, this 返回的都是一个对象):

  1. 在函数体中,非显式或隐式地递减调用函数时,在严格模式下,函数内的 this 会绑定到 underfined 上, 在非严格模式下则会被绑定到全局对象 window / global 上。
  2. 一般使用 new 方法调用构造函数时,构造函数内的 this 会被绑定到新创建的对象上
  3. 一般通过 call / apply / bind 方法显式调用函数时,函数体内的 this 会被你绑定到指定参数的对象上
  4. 一般通过上下文对象调用函数时,函数体内的 this 会被绑定到该对象上
  5. 在箭头函数中, this 的指向是由外层(函数或全局)作用域来决定的, 箭头函数的 this 一旦确定就不可更改了
//例子1
function fn1() {
    console.log(this); //window
}
fn1();

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


//例子2
var foo = {
    bar: 10,
    fun() {
        console.log(this);
        console.log(this.bar)
    }
}
var fn2 = foo.fun;
fn2(); // window undefineds
foo.fun() // {bar:10, fun:f}  10


//例子3 : 上下文对象
var studen = {
    name: 'zhangsna',
    fn() {
        return this
    }
}
console.log(studen.fn() === studen); // true

// 例子 4
var studen = {
    name: 'zhangsna',
    son: {
        name: 'zhangxiaosan',
        fn() {
            return this.name;
        }
    }
}
console.log(studen.son.fn()) // zhangxiaosan


// 例子 5
var o1 = {
    text: 'o1',
    fn() {
        return this.text;
    }
}
var o2 = {
    text: 'o2',
    fn() {
        return o1.fn();
    }
}
var o3 = {
    text: 'o3',
    fn() {
        var fn2 = o1.fn;
        return fn2(); // 这里对 fn2 的调用是全局调用, 也就是普通函数的调用
    }
}
console.log(o1.fn()); // o1
console.log(o2.fn()); // o1
console.log(o3.fn()); // undefined

//例子 6
var obj = {}

function fn() {
    return this;
}
console.log(fn() === window) // true  这里是普通函数的调用
console.log(fn.call(obj) === obj) // true ,这里使用 call 改变了 this 的指向 

//但是 call 绑定的对象是 null 、 undefined 或则为空 ,则结果仍是 window
console.log(fn.call()); // window
console.log(fn.call(null)); //window
console.log(fn.call(undefined)); //window

//如果call 传参不是以上类型,则转化成对应的包装对象
console.log(fn.call(5)) // Number{5}


// 例子 7
var counter = {
    count: 0,
    add() {
        this.count++;
    }
}
var fn = counter.add.bind(counter);
fn(); // 普通函数的调用,但是绑定了 this 指向
console.log(counter.count); // 1
var fn2 = counter.add;
fn2(); // 这里是普通函数的调用,没绑定 this 
console.log(counter.count); // 1


//例子 8  bind()  返回的是一个函数
var counter = {
    count: 0,
    add() {
        this.count++;
    }
}
var obj = {
    count: 100
}
var fn = counter.add.bind(obj);
fn();
console.log(counter.count); // 0
console.log(obj.count) // 101


//例子 9
var counter = {
    count: 0,
    add() {
        'use strict'
        this.count++;
    }
}

function callback(fn) {
    fn();
}
callback(counter.add.bind(counter));
console.log(counter.count); // 1


// 例子 10
var obj = {
    name: 'zhangsan',
    arr: [1, 2, 3],
    print() {
        this.arr.forEach(function (n) {
            console.log(n)
            console.log(this.name)
        })
    }
}
obj.print(); // 1 undefined 2 undefined 3 undefinde

// 例子 11
var obj = {
    name: 'zhangsan',
    arr: [1, 2, 3],
    print() {
        this.arr.forEach(function (n) {
            console.log(n)
            console.log(this.name)
        }.bind(this))
    }
}
obj.print(); // 1 zhangsan 2 zhangsan 3 zhangsan

// //例子 12
var obj = {
    name: 'zhangsan',
    arr: [1, 2, 3],
    print() {
        this.arr.forEach((n) => {
            console.log(n)
            console.log(this.name)
        })
    }
}
obj.print(); // 1 zhangsan 2 zhangsan 3 zhangsan

//例子 13
var x = 20;
const obj = {
    x: 10,
    test: function () {
        console.log(this);
        console.log(this.x);
    }
}
obj.test(); // obj{}  10

// //例子 13
var x = 20;
const obj = {
    x: 10,
    test: () => {
        console.log(this);
        console.log(this.x);
    }
}
obj.test(); // window  20


// 例子 14
var name = 'javascript';
const obj = {
    name: 'php',
    test: function () {
        console.log(this) // obj{}
        console.log(this.name) // php
        const i = function () {
            console.log(this)
            console.log(this.name);
        }
        i(); // window javascript
    }
}
obj.test(); // 这里的 i() 相当于是 全局普通函数的调用


//例子 15
var name = 'javascript';
const obj = {
    name: 'php',
    test: () => {
        console.log(this) // window
        console.log(this.name) // javascript
        const i = function () {
            console.log(this)
            console.log(this.name);
        }
        i(); // window javascript
    }
}
obj.test(); // 这里的 i() 相当于是 全局普通函数的调用

//例子 16
const a = 13
const obj = {
    a: 13,
    b: () => {
        console.log(this.a)
    },
    c: function () {
        console.log(this.a)
    },
    d: function () {
        return () => {
            console.log(this)
        }
    },
    e: function () {
        return this.b
    }
}
obj.b(); // undefined 
obj.c(); // 13
obj.d()(); // obj
obj.e()(); // underfined

提供一些更多的联系题链接:https://juejin.cn/post/6844904083707396109

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值