Blogger Information
Blog 22
fans 0
comment 1
visits 17590
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
第十一章 this指向深入
刘静的博客
Original
687 people have browsed it

第十一章 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.间接调用

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!