博客列表 >第十一章 this指向深入

第十一章 this指向深入

刘静的博客
刘静的博客原创
2020年08月29日 22:12:13686浏览

第十一章 this指向深入

this的绑定规则- 默认绑定

this默认指向了window

1.全局环境下的this指向了window

  1. console.log(this);

2.函数独立调用,函数内部的this也指向了window

  1. function fn(){
  2. console.log(this);
  3. }
  4. fn();

3.被嵌套的函数独立调用时,this默认指向了window

  1. var a = 0;
  2. var obj = {
  3. a:2,
  4. foo:function (){
  5. //函数当做对象的方法来调用 this指向了obj
  6. var that = this;
  7. function test(){
  8. console.log(that.a);//2,test()函数内部指向window对象,obj.foo()指向obj对象,将obj对象赋值给变量that
  9. }
  10. test();
  11. }
  12. }
  13. obj.foo();

4.IIFE 自执行函数中内部的this指向了window

  1. var a = 10;
  2. function foo(){
  3. console.log(this);//{a: 2, foo: ƒ}
  4. (function test(that){
  5. console.log(that.a);//2
  6. })(this);
  7. }
  8. var obj = {
  9. a:2,
  10. foo:foo
  11. }
  12. obj.foo();
  13. (function (){
  14. console.log('自执行函数中内部的this:'+ this);////自执行函数中内部的this:[object Window]
  15. })()

5.闭包中this默认指向了window

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

隐式绑定

当函数当做方法来调用,this指向了直接对象

  1. function foo(){
  2. console.log(this.a);//1
  3. }
  4. var obj = {
  5. a:1,
  6. foo:foo,
  7. obj2:{
  8. a: 2,
  9. foo:foo
  10. }
  11. }
  12. // foo()函数的直接对象是obj,this的指向指向了直接对象
  13. obj.foo();
  14. // foo()函数的直接对象是obj2,this的指向指向了直接对象
  15. obj.obj2.foo();//2

隐式丢失

隐式丢失就是指被隐式绑定的函数丢失了绑定对象 从而默认绑定到window

1.隐式丢失 函数别名

  1. var a = 0;
  2. function foo(){
  3. console.log(this.a);
  4. }
  5. var obj = {
  6. a: 1,
  7. foo:foo
  8. }
  9. // 把obj.foo()赋值给别名bar,造成隐式丢失的情况.因为只是把obj.foo()赋值了bar变量.而bar与obj对象毫无关系
  10. //第一种写法
  11. var bar = obj.foo();
  12. bar();
  13. //第二种写法
  14. var a = 0;
  15. var bar = function foo(){
  16. console.log(this.a);
  17. }
  18. bar();

2.参数传递

  1. //第一种写法
  2. var a = 0;
  3. function foo(){
  4. console.log(this.a);
  5. }
  6. function bar(fn){
  7. fn();
  8. }
  9. var obj = {
  10. a: 1,
  11. foo:foo
  12. }
  13. // 把obj.foo当做参数传递到bar函数中,有隐式的函数赋值 fn = obj.foo,只是把foo函数赋值给了fn,而fn与obj对象毫无关系,所以当前foo函数内部的this指向了window
  14. bar(obj.foo)
  15. //第二种写法
  16. var a = 0;
  17. function bar(fn){
  18. fn();
  19. }
  20. bar(function foo(){
  21. // 内部的this指向了window
  22. console.log(this.a);
  23. })

3.内置函数 setTimeout()和setInterval()第一个参数的回调函数中的this默认指向了window,跟第二种情况是类似

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

4.间接调用

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

隐式绑定,函数当做对象中的方法来使用,内部的this指向了该对象

  1. obj.foo();//3

将obj.foo函数对象赋值给p.foo函数,然后立即执行。相当于仅仅是foo()函数的立即调用,内部的this默认指向了window (p.foo = obj.foo)();

将obj.foo赋值给p.foo函数,之后p.foo()函数再执行,其实是属于p对象的方法的指向,this指向了当前的p对象

  1. p.foo = obj.foo;
  2. p.foo();//4

5.其它情况 指向了window的特殊情况

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

显示绑定

1.显示绑定:call() apply() bind()把对象绑定到this上

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

[^注意:bind()返回的是一个函数对象]:

2.硬绑定是显示绑定的一个变种,使得this不能再被改变

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

3.数组的forEach(fn,对象) map() filter() some() every()

  1. var id = 'window';
  2. function fn(el){
  3. console.log(el,this.id);//"window"
  4. }
  5. var obj = {
  6. id: 'fn'
  7. }
  8. var arr = [1,2,3];
  9. // arr.forEach(fn);
  10. arr.forEach(function(el,index){
  11. console.log(el,index,this);////1 0 {id: "fn"} 2 1 {id: "fn"} 3 2 {id: "fn"}
  12. },obj);

new绑定

1.如果是new关键来执行函数 相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象

  1. function fn(){
  2. console.log(this);//fn2 {}
  3. return;
  4. }
  5. var fn = new fn();
  6. console.log(fn);
  1. function fn2(){
  2. // this还是指向了当前的对象
  3. console.log(this);
  4. // 使用return关键来返回对象的时候,实例化出来的对象是当前的返回对象
  5. return {
  6. name:'mjj'
  7. }
  8. return this;
  9. }
  10. var fn2 = new fn2();
  11. console.log(fn2);//{name: "mjj"}
  12. var person = {
  13. fav: function (){
  14. return this;
  15. }
  16. }
  17. var p = new person.fav();
  18. console.log(p,p === person);//fav {}, false

严格模式下this的指向

1.严格模式下,独立调用的函数内部的this指向了undefined

  1. function fn(){
  2. 'use strict';
  3. console.log(this);
  4. }
  5. fn();

2.严格模式下,函数apply()和call()内部的this始终是它们的第一个参数

  1. var color = 'red';
  2. function showColor(){
  3. 'use strict';
  4. console.log(this);//undefined
  5. console.log(this.color);//Cannot read property 'color' of undefined
  6. }
  7. showColor.call(undefined);

this总结

总结:

​ 1.默认绑定

​ 2.隐式绑定

​ 3.显式绑定

​ 4.new绑定

​ 分别对应函数的四种调用:

​ - 独立调用

​ - 方法调用

​ - 间接调用

​ call() apply() bind()

​ - 构造函数调用

隐式丢失:

​ 1.函数别名

​ 2.函数当做参数传递

​ 3.内置函数

​ 4.间接调用

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议