资讯专栏INFORMATION COLUMN

你不知道的this

zoomdong / 612人阅读

摘要:话不多说,让我们一起探讨你不知道的牛刀小试答案初露锋芒答案函数,第行是一个定时器,哪怕定时器的延迟时间为,仍然先执行第行。故为当使用定时器调用函数时,先执行函数内代码,在进行函数调用。如果都不是的话,使用默认绑定。

MDN中的this定义

当前执行代码的环境对象。

多么简约凝练的概括,寥寥11个字,将伴随程序员的前世今生。话不多说,让我们一起探讨你不知道的this

牛刀小试
  function foo() {
      console.log( this.a );
  }
  var a = 10;
  foo();
答案:
10
this —> window
  function foo() { 
      console.log( this.a );
  }
  var obj2 = { 
      a: 42,
      foo: foo 
  };
  var obj1 = { 
      a: 2,
      obj2: obj2 
  };
  obj1.obj2.foo(); 
42
this -> obj2
初露锋芒
  function foo() {
      setTimeout(() => this.a = 1, 0)
      console.log( this.a );
  }
  function foo2() {
      setTimeout(() => this.a = 1, 500)
      console.log( this.a );
  }
  function doFoo(fn) {
      this.a = 4
      fn();
  }
  var obj = {
      a: 2,
      foo: foo,
      foo2: foo2
  };
  var a =3
  doFoo( obj.foo );
  setTimeout( obj.foo, 0 )
  setTimeout( obj.foo2, 100 )
答案:
4
1
1
foo函数,第2行是一个定时器,哪怕定时器的延迟时间为0,仍然先执行第3行。故为4
当使用定时器调用函数时,先执行函数内代码,在进行函数调用。故为1
同理: 故为1
展露头脚
a = 3
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2
};
foo.call( obj ); 
foo.call( null );
foo.call( undefined ); 
foo.call(  ); 
var obj2 = {
    a: 5,
    foo
}
obj2.foo.call() // 3,不是5!
//bind返回一个新的函数
function foo(something) {
    console.log( this.a, something );
    return this.a + something;
}
var obj = {
    a: 2
}
var bar = foo.bind( obj );
var b = bar( 3 ); 
console.log( b );
答案:
2 undefined
3 undefined
3 undefined
3 undefined
3 undefined
2 3
5
第8行: this -> obj = 2, msg没有传值,故为undefined
第9~12行: 当call的第一个参数为null, undefined或者不传值时,只想window, this -> window = 3, msg没有传值,故为undefined
第25行:bind改变指向 -> obj,第26行:msg为3, 故为2 3
第27行:执行函数,为2+3 = 5
锐不可当 隐式丢失

一个最常见的 this绑定问题就是被隐式绑定的函数会丢失绑定对象,也就是说它会应用默认绑定,从而把 this 绑定到全局对象或者 undefined 上,取决于是否是严格模式

function foo() { 
    console.log( this.a );
}
function doFoo(fn) {
    fn()
}
var obj = {
    a: 2,
    foo: foo 
};
var a = "oops, global";
doFoo( obj.foo ); 
答案: oops, global
第5行fn()引用第位置其实foo, 因此doFoo()相当于是一个不带修饰符的函数调用,因此应用了默认绑定—> window = oops, global
舍我其谁
function foo(something) { 
    this.a = something;
}
var obj1 = { 
    foo: foo
};
var obj2 = {};
obj1.foo( 2 );
console.log( obj1.a );
obj1.foo.call( obj2, 3 );
console.log( obj2.a );
var bar = new obj1.foo( 4 ); 
console.log( obj1.a );
答案:
2
3
2
4
new 绑定比隐式绑定优先级高,也闭隐式绑定绑定优先级高
总结

函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象。
var bar = new foo()

函数是否通过call、apply(显式绑定)或者硬绑定调用?如果是的话,this绑定的是 指定的对象。
var bar = foo.call(obj2)

函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上 下文对象。
var bar = obj1.foo()

如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到 全局对象。
var bar = foo()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106865.html

相关文章

  • 你不知道Virtual DOM(五):自定义组件

    摘要:现在流行的前端框架都支持自定义组件,组件化开发已经成为提高前端开发效率的银弹。二对自定义组件的支持要想正确的渲染组件,第一步就是要告诉某个标签是自定义组件。下面的例子里,就是一个自定义组件。解决了识别自定义标签的问题,下一步就是定义标签了。 欢迎关注我的公众号睿Talk,获取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...

    lk20150415 评论0 收藏0
  • 你不知道Virtual DOM(六):事件处理&异步更新

    摘要:如果列表是空的,则存入组件后将异步刷新任务加入到事件循环当中。四总结本文基于上一个版本的代码,加入了事件处理功能,同时通过异步刷新的方法提高了渲染效率。 欢迎关注我的公众号睿Talk,获取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的两大前端框架,React和Vue,都不约而同的借助Virtual DO...

    caozhijian 评论0 收藏0
  • 你不知道JavaScript》 (下) 阅读摘要

    摘要:本书属于基础类书籍,会有比较多的基础知识,所以这里仅记录平常不怎么容易注意到的知识点,不会全记,供大家和自己翻阅不错,下册的知识点就这么少,非常不推介看下册上中下三本的读书笔记你不知道的上读书笔记你不知道的中读书笔记你不知道的下读书笔记第三 本书属于基础类书籍,会有比较多的基础知识,所以这里仅记录平常不怎么容易注意到的知识点,不会全记,供大家和自己翻阅; 不错,下册的知识点就这么少,非...

    Jacendfeng 评论0 收藏0
  • 你不知道javascript》笔记_this

    下一篇:《你不知道的javascript》笔记_对象&原型 写在前面 上一篇博客我们知道词法作用域是由变量书写的位置决定的,那this又是在哪里确定的呢?如何能够精准的判断this的指向?这篇博客会逐条阐述 书中有这样几句话: this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式当一个函数被调用时...

    cpupro 评论0 收藏0
  • 你不知道JavaScript》 (上) 阅读摘要

    摘要:但是如果非全局的变量如果被遮蔽了,无论如何都无法被访问到。但是如果引擎在代码中找到,就会完全不做任何优化。结构的分句中具有块级作用域。第四章提升编译器函数声明会被提升,而函数表达式不会被提升。 本书属于基础类书籍,会有比较多的基础知识,所以这里仅记录平常不怎么容易注意到的知识点,不会全记,供大家和自己翻阅; 上中下三本的读书笔记: 《你不知道的JavaScript》 (上) 读书笔记...

    FingerLiu 评论0 收藏0
  • 你不知道javascript (1) --- this

    摘要:的定义执行上下文。这本书也是举了好几个例子来说明,这句话的含义。我个人也认为,不通过代码,非常难说明问题。所以,修改的是全局的,并不是自身的。 this 先说明一下,this是我JavaScript的盲区,写这篇文章,就是为了让自己能重新认识this,并且搞清楚,js里面的this,到底是什么。 这个系列主要是记录我自己看《你不知道的JavaScript》这本书的笔记。 this的定义...

    Corwien 评论0 收藏0

发表评论

0条评论

zoomdong

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<