默认全局变量为 window
优先级:new>显示绑定>隐式绑定>默认绑定
概要
- function函数this绑定规则
- 构造函数return this 之外的东西,生成的对象和this指向的情况
- 箭头函数this指向
- 例题
function函数
默认绑定
独立调用,指向window
console.log(this===window) //true
隐式绑定
谁调用就指向谁
函数执行才会有this,每个函数都有自己的this,this指向是否相等由函数执行方式决定
let obj = { foo : function(){ console.log(this); //obj function test(){ console.log(this); } test() //独立调用 指向window (function(){ console.log(this); //同上 window })(); function back(){ console.log(this); } return back; } } let a = obj.foo() // obj window window a(); //window 独立调用
// 变量赋值 function foo(){ console.log(this); } let obj = { foo : foo } obj.foo(); //obj let a = obj.foo; //隐式丢失 a(); // window
// 参数赋值 // 预编译过程中,实参被赋值为形参,值的浅拷贝的过程 function foo(){ console.log(this); } function bar(fn){ fn(); new fn; // foo {} } let obj = { foo : foo } bar(obj.foo); //window
// api 回调函数中的this 参考api文档 let arr = [1,2,3]; arr.forEach((item,idx,arr)=>{ console.log(this) //window }); arr.forEach((item,idx,arr)=>{ console.log(this) //obj },obj);
显示绑定
call,apply,bind
new绑定
指向实例化对象
function obj(){ let this = {}; .................... return this; }
如果构造函数return this之外的东西,生成的对象和this指向:
function foo(){ this.a = 2; console.log(this); //{a:2} return { o : 0 }; } let f = new foo; console.log(f); // {O:0}
function foo(){ this.a = 2; console.log(this); //{a:2} return 1; } let f = new foo; console.log(f); //{a:2}
function foo(){ this.a = 2; console.log(this); //{a:2} return "asd"; } let f = new foo; console.log(f); //{a:2}
箭头函数
本身没有this,不受绑定影响,this指向由外层函数作用域决定
function foo(){ console.log(this); let test = ()=>{ console.log(this); } return test; } let obj1 = { foo : foo } let obj2 = { foo : ()=>{ console.log(this); } } let o = obj1.foo(); // foo{} let p = foo().call(obj); // window o(); // foo{} 默认绑定无效 obj1.foo(); // window 隐式绑定无效 p(); // window 显示绑定无效 let er = new foo(); // Error 箭头函数不允许作为构造函数
做做题把~~
function foo(s){ this.a = s; } let obj = {}; let bar = foo.bind(obj); bar(2); console.log(obj.a); let baz = new bar(3); console.log(obj.a); console.log(baz.a); // 2 2 3
let name = 'window' let obj1 = { name : '1', fn1 : function () { console.log(this.name); }, fn2 : ()=> console.log(this.name), fn3 : function(){ return function(){ console.log(this.name); } }, fn4 : function(){ return ()=> console.log(this.name); } } let obj2 = { name : '2' } obj1.fn1(); obj1.fn1.call(obj2); obj1.fn2(); obj1.fn2.call(obj2); obj1.fn3()(); obj1.fn3().call(obj2); obj1.fn3.call(obj2)(); obj1.fn4()(); obj1.fn4().call(obj2); obj1.fn4.call(obj2)(); // 1 // 2 // window // window // window // 2 // window // 1 // 1 // 2