常见的this指向
1、全局作用域中或者普通函数中this指向全局对象window
2、立即执行函数this必定指向window
3、定时器this指向window
4、事件中this指向事件源对象
5、方法中谁调用就指向谁
6、构造函数中this指向对象实例
- 默认绑定
- 隐式绑定
- 显式绑定(call,apply,bind)
- new关键字
- 箭头函数this指向问题
默认绑定
function aa(){
console.log(this);// window
}
function bb(){
'use strict';
console.log(this);// undefined
}
var a = 1;
function cc(){
var a = 2;
console.log(this.a);//1;
}
/**变形**/
var a =1;
function ee(){
var a = 2;
function inner(){
console.log(this.a)// 1
}
inner();
}
let b = 1;
function dd(){
let b = 2;
function inner(){
console.log(this.b);// undefined
}
inner();
}
const c = {
a: 1,
fn: function(){
console.log(this.a);
}
}
c.fn();//1
const d = c.fn;
d();// undefined;
隐式绑定:属性访问调用,this指向调用堆栈的上一级
function fn(){
console.log(this.a);
}
const f = { a: 1 }
f.fn = fn;
f.fn();// 1
let obj1 = { a: 1, fn}
let obj2 = { a: 2, obj1}
obj2.obj1.fn();//1
隐式绑定失效的例子: 1、将对象的函数赋给一个变量,执行变量();此时this已指向全局环境
var obj = {
a: 1,
fn: function(){
console.log(this.a);
}
}
var value = obj.fn;
value();
2、setTimeout函数中的回调函数,this指向全局
setTimeout(obj.fn, 1000);
3、函数做参数的时候
function run(fn){
fn();
}
run(obj.fn);
4、匿名函数
var name = "global";
var obj = {
name: "jubu",
fn: function(){
return function(){
console.log(this.name);
}
}
}
obj.fn()();
5、函数赋值也会改变this指向
6、IIFE(立即执行函数)
显式绑定(call,apply,bind)
call、apply、bind bind返回一个新函数,新函数指向绑定的对象,旧函数不会
注意以下情况不同:
function fn() { console.log(this.val)}
var obj = { val : 100}
fn.call(obj);// 100
fn.call(null);// undefined,绑定到全局
// bind
function fn() { console.log(this)}
fn.bind(1).bind(2)();// Number {1}
new绑定
this指向函数实例化之后的对象
function myNew(){
var o = {};
constructor = [].shift.call(arguments);
o.__proto__ = constructor.prototype;
var returnObj = constructor.call(o, ...arguments);
if(typeof returnObj === 'object' || !Object.is(returnObj, null)){
return returnObj;
}
return o;
}
function aaa(names){ console.log(names)}
myNew(aaa,'a');
绑定规则优先级
new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
箭头函数this指向问题
箭头函数没有自己的this指向,它的this指向上一级作用域的this 箭头函数 没有this 没有arguments,没有原型链