总结


1.默认绑定规则 console.log(this===window)//true
2.
有优先级4>3>2>1,隐式绑定偷偷绑定,编译器自动绑定
独立调用、对象调用、显示绑定调用
1.默认绑定规则

1.默认绑定规则:
console.log(this===window)//trueconsole.log({}==={})//false
函数独立调用
function test(){console.log(this=== window)}test()
true,函数没有new,this指向window,其实是window.test()的简写,其实也可以看作window调用
独立调用就指向window:与方式有关,有地方无关,只要独立调用就指向window
2.隐式绑定规则

var a=0;var obj={a:2,foo:function() {console.log(this)}}obj.foo()
obj 函数内部的this指向,obj调用函数,可以看作obj.foo再执行
obj调用函数执行,函数内的this指向obj,指向调用者

var a=0;var obj={a:2,foo:function() {console.log(this)//objfunction test(){console.log(this)//window}test()}}obj.foo()

预编译会有AO、GO,AO、GO里面有this,this在预编译时确定,每个函数中都会有this指向问题,因为this存在于AO、GO中,所以只有在函数执行才有this指向问题,不执行没有
因为它俩是不同函数,有不同的AO,所以this是不一样的,但存在指向同一个地址的可能性
obj是对象,不是函数,不能执行,没有AO也就没有this指向,obj就是存储数据的,属性和方法都是数据
function方法存储代码块,片段
test()就是独立调用,独立调用就指向window,看的是调用的方式,不是在哪调用

var a = 0;var obj = {a: 2,foo: function () {console.log(this);//obj// function test(){// console.log(this)// }// test(); (function () {console.log(this)//window})();}}obj.foo();
同样是window,因为立即执行函数,相当于声明函数,再执行,和上面的声明test再执行意思是一样的

var a = 0;var obj = {a: 2,foo: function () {console.log(this);// function test(){// console.log(this)// }// test()// ; (function () {// console.log(this)// })();function test(){console.log(this);}return test;//当函数执行的时候,导致函数被定义,并抛出}}obj.foo()();// var a=obj.foo();// a()
还是window,obj.foo()相当于test函数,obj.foo()()相当于test()函数执行,这是独立调用,this是window
变量赋值:隐式丢失

var a=0;function foo(){console.log(this);}var obj = {a:2,foo:foo/* 相当于foo:function foo(){...}属性foo指向函数foo,指向可以看作复制一份代码到此处*/}obj.foo();//obj//隐式丢失var bar=obj.foo;bar();//window

把bar指向方法foo但没有执行,bar()再执行,相当于foo()
当方法被赋值时会产生隐式丢失
参数赋值的情况

var a = 0;function foo() {console.log(this);}function bar(fn) {fn()}var obj = {a: 2,foo: foo}bar(obj.foo)//window


obj.foo相当于函数foo(),bar(foo)相当于func bar(){ foo() },独立调用

var a = 0;function foo() {console.log(this);}function bar(fn) {// console.log(this);fn(obj)// new fn();// fn.bind(obj)();}var arr=[1,2,3]arr.forEach(function(item,idx,arr) {})//父函数是有能力决定 子函数的this指向的;var obj = {a: 2,foo: foo}//预编译的过程中,实参被赋值为形参;(值的拷贝的过程,前拷贝);bar(obj.foo)//window
父函数是有能力决定 子函数的this指向的;
比如fn.call,arr数组的方法forEach的参数中有this的参数,可以指定forEach参数函数的this指向

var arr=[1,2,3];arr.forEach(function(item,idx,arr){console.log(this)})arr.sort(function(a,b){console.log(this);return a-b;})// setInterval(function() {// console.log(this)// })
3.显示绑定
call等








undefined、null没有包装类,绑定必须是对象,绑定失败,执行默认绑定方式
4.new绑定

function Person(){var this={};this.a=1;return this;}var person=new Person();
this指向实例对象,new默认返回this,并且隐式把this从指向window变成指向实例对象
var person=new Person();console.log(person)console.log(typeof person)

因为返回的是this={},所以typeof是object

call优先级更大

返回{}object,返回引用值会替代this引用值

var name='222';var a={name :'111',say:function() {console.log(this.name)}}var fun=a.say;/*相当于var fun=function(){console.log(this.name)}*/fun();//222 独立调用 this指向windowa.say();//111 对象调用
222 111
