JavaScript中this的指向问题及面试题你掌握了吗?
this 作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的。这里先做一个结论,重要事情说三遍:
this的指向是由上下文环境动态决定的
this的指向是由上下文环境动态决定的
this的指向是由上下文环境动态决定的
this指向实例场景 关于this的指向的不确定性,主要体现在如下几个应用场景中:
全局环境 普通函数调用 由call/apply/bind函数调用 对象属性方法调用 构造函数调用 箭头函数 全局环境 在全局环境中无论是否是严格模式,this 均指向全局对象,例如浏览器端的 window
// 在浏览器中, window 对象同时也是全局对象: ```javascript console.log(this === window); // true a = 37; console.log(window.a); // 37 this.b = "MDN"; console.log(window.b) // "MDN" console.log(b) // "MDN"
普通函数调用 当普通的函数,直接调用的时候,一般来说分两种情况: 严格模式绑定到 undefined 非严格模式绑定到全局对象 window ```javascript function foo(){ console.log(this); } function bar(){ "use strict"; console.log(this); } foo() // window bar() // undefined
call/apply/bind函数调用 call/apply 这两个函数对象到方法能立即执行某个函数,并且讲函数中的this绑定到你提供到对象上去
bind 方法永久的绑定函数中的this到指定对象上,并返回一个新函数,将来这个函数无论怎么调用都可以
function foo(){ console.log(this); } function bar(){ console.log(this); } foo.call({ name:小米}); // {name: "小米"} const bar1 = bar.bind({ num:123}) bar1() // {num: 123}
对象属性方法调用 作为对象属性方法调用,都指向前面调用函数都那个对象。当然有的时候会出现各种变种或者干扰的面试题
const student = { name: "tom", fn: function () { return this; }, }; console.log(student.fn() === student);
构造函数调用或者类上下文 构造函数作为JavaScript创建对象的那只大母鸡(实际上类是构造函数的语法糖),通常程序界有个段子叫做new 一个对象,谁还敢说程序员(媛)没有对象的,这种方式调用this指向的是你new出来的那个对象实例本身:
function Person(name){ console.log(this); this.name = name } const p = new Person(tom) console.log(p);
箭头函数中的this 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
var obj = { name: "tom", foo() { setTimeout(() => { console.log(this); }, 1000); }, }; obj.foo() // obj
面试题 常见面试题有: 1、手写bind函数
Function.prototype.mybind = function (ctx, ...args) { const fn = this; return function () { fn.apply(ctx, args); }; }; function foo(x, y) { console.log(this, x, y); } const foo1 = foo.mybind({ name: "zhangsan" }, 10, 20); foo1();
2、new 操作符调用构造函数,具体做了什么?
创建一个新的对象; 将构造函数的 this 指向这个新对象; 为这个对象添加属性、方法等; 最终返回新对象。