P184

总结

image.png
image.png
1.默认绑定规则 console.log(this===window)//true
2.

有优先级4>3>2>1,隐式绑定偷偷绑定,编译器自动绑定
独立调用、对象调用、显示绑定调用

1.默认绑定规则

image.png
1.默认绑定规则:

  1. console.log(this===window)//true
  2. console.log({}==={})//false

引用值,引用值对比指针地址,指向同一片空间才是true
image.png

函数独立调用

  1. function test(){
  2. console.log(this=== window)
  3. }
  4. test()

true,函数没有new,this指向window,其实是window.test()的简写,其实也可以看作window调用
独立调用就指向window:与方式有关,有地方无关,只要独立调用就指向window

2.隐式绑定规则

image.png

  1. var a=0;
  2. var obj={
  3. a:2,
  4. foo:function() {
  5. console.log(this)
  6. }
  7. }
  8. obj.foo()

obj 函数内部的this指向,obj调用函数,可以看作obj.foo再执行
obj调用函数执行,函数内的this指向obj,指向调用者
image.png

image.png

  1. var a=0;
  2. var obj={
  3. a:2,
  4. foo:function() {
  5. console.log(this)//obj
  6. function test(){
  7. console.log(this)//window
  8. }
  9. test()
  10. }
  11. }
  12. obj.foo()

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

image.png

  1. var a = 0;
  2. var obj = {
  3. a: 2,
  4. foo: function () {
  5. console.log(this);//obj
  6. // function test(){
  7. // console.log(this)
  8. // }
  9. // test()
  10. ; (function () {
  11. console.log(this)//window
  12. })();
  13. }
  14. }
  15. obj.foo();

同样是window,因为立即执行函数,相当于声明函数,再执行,和上面的声明test再执行意思是一样的

image.png

  1. var a = 0;
  2. var obj = {
  3. a: 2,
  4. foo: function () {
  5. console.log(this);
  6. // function test(){
  7. // console.log(this)
  8. // }
  9. // test()
  10. // ; (function () {
  11. // console.log(this)
  12. // })();
  13. function test(){
  14. console.log(this);
  15. }
  16. return test;
  17. //当函数执行的时候,导致函数被定义,并抛出
  18. }
  19. }
  20. obj.foo()();
  21. // var a=obj.foo();
  22. // a()

还是window,obj.foo()相当于test函数,obj.foo()()相当于test()函数执行,这是独立调用,this是window
image.png

变量赋值:隐式丢失

image.png

  1. var a=0;
  2. function foo(){
  3. console.log(this);
  4. }
  5. var obj = {
  6. a:2,
  7. foo:foo
  8. /* 相当于foo:function foo(){...}
  9. 属性foo指向函数foo,指向可以看作复制一份代码到此处*/
  10. }
  11. obj.foo();//obj
  12. //隐式丢失
  13. var bar=obj.foo;
  14. bar();//window

image.png
把bar指向方法foo但没有执行,bar()再执行,相当于foo()
当方法被赋值时会产生隐式丢失

参数赋值的情况

image.png

  1. var a = 0;
  2. function foo() {
  3. console.log(this);
  4. }
  5. function bar(fn) {
  6. fn()
  7. }
  8. var obj = {
  9. a: 2,
  10. foo: foo
  11. }
  12. bar(obj.foo)//window

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

image.png

  1. var a = 0;
  2. function foo() {
  3. console.log(this);
  4. }
  5. function bar(fn) {
  6. // console.log(this);
  7. fn(obj)
  8. // new fn();
  9. // fn.bind(obj)();
  10. }
  11. var arr=[1,2,3]
  12. arr.forEach(function(item,idx,arr) {
  13. })
  14. //父函数是有能力决定 子函数的this指向的;
  15. var obj = {
  16. a: 2,
  17. foo: foo
  18. }
  19. //预编译的过程中,实参被赋值为形参;(值的拷贝的过程,前拷贝);
  20. bar(obj.foo)//window

父函数是有能力决定 子函数的this指向的;
比如fn.call,arr数组的方法forEach的参数中有this的参数,可以指定forEach参数函数的this指向
image.png
image.png

  1. var arr=[1,2,3];
  2. arr.forEach(function(item,idx,arr){
  3. console.log(this)
  4. })
  5. arr.sort(function(a,b){
  6. console.log(this);
  7. return a-b;
  8. })
  9. // setInterval(function() {
  10. // console.log(this)
  11. // })

this都是window

3.显示绑定

call等
image.png
image.png

image.png
image.png

image.png
image.png

image.png
image.png

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

4.new绑定

image.png

  1. function Person(){
  2. var this={};
  3. this.a=1;
  4. return this;
  5. }
  6. var person=new Person();

this指向实例对象,new默认返回this,并且隐式把this从指向window变成指向实例对象

  1. var person=new Person();
  2. console.log(person)
  3. console.log(typeof person)

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

image.png
call优先级更大
image.png
image.png
返回{}object,返回引用值会替代this引用值

image.png

  1. var name='222';
  2. var a={
  3. name :'111',
  4. say:function() {
  5. console.log(this.name)
  6. }
  7. }
  8. var fun=a.say;
  9. /*相当于var fun=function(){console.log(this.name)}*/
  10. fun();//222 独立调用 this指向window
  11. a.say();//111 对象调用

222 111