默认全局变量为 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