JS This 指向谁

this 决定在于函式如何被呼叫

Why use This

可用不同物件,调用同函式使 API 更简洁且易于复用
function identify() { console.log(this.name) }let me = { name: "Tom" }let you = { name: "Mark" }identify.call(me) // Tomidentify.call(you) // Mark

影响 this 的情境

默认绑定 => 指向 global 物件

纯粹的调用、直接呼叫Function严格模式("use strict") => 指向 undefined
  // 浏览器的 global物件 window  console.log(this) // window    // 浏览器的 global物件 window   function test(){ console.log(this) }  test()

隐式绑定 => 指向 上下文 物件

物件 => 指向 物件隐式绑定丢失: 函式调用的时候,无上下文,只是对函式的引用
  const obj = {    test(){ console.log(this) }  }  const bar = obj.test  // 等同于此 const bar = test(){ console.log(this) }  bar() // window

new 绑定 ( new建构式 )

new 关键字会作

建立新物件连接 Prototypethis 绑定至该新物件 (相当于物件绑定)
  const name = '全域'  const callMethod = function () {    this.name = 'Mark'    console.log(this.name)  }    const myName = new callMethod()  console.log(myName.name) // Mark

DOM 物件

this 指向 挂载事件的元件 e.currentTarget
  const parent = document.querySelector('.parent')  parent.addEventListener('click', test)  function test(e) {      // e.target 指向触发事件的元件  .child    console.log('e.target',e.target);        // e.currentTarget 指向挂载事件的元件 .parent    console.log('e.currentTarget',e.currentTarget);        // this 指向挂载事件的元件  .parent 即 e.currentTarget    console.log('this',this);  }

显式绑定 => 强制绑向目标

bind / apply / call => 指向 目标

箭头函式

箭头函式 => 指向 上一个非箭头函式的 this
因箭头函式不会产生this,而会照 Scope Chain 向上找箭头函式不可当建构式

闭包的this

纯粹的调用 => window
  const name = '全域';  function callMethod() {    const name = '区域'    console.log(this.name) // '全域'    return function () {  // 闭包      const name = '区域的内层变数'      console.log(this.name) // '全域'    }  }  // 分两段 callMethod() 回传内部函式  // 内部函式() 执行,其环境在 window   callMethod()()

Object & ArrowFunction

缩写与否 效果一样ArrowFunction 指向上一个非箭头函式的This
  const name = '全域'  const object = {    name: 'Object 区域',    callMethod: function () {      const name = '区域'      console.log(this.name) // 区域 (指向物件)    },    abbCallMethod () {      const name = '缩写函式区域'      console.log(this.name) // 区域 (指向物件)    },    arrowCallMethod: () => {      const name = '箭头函式区域'      console.log(this.name) // 全域    },  }  object.callMethod()  object.abbCallMethod()    // 指向上一个非箭头函式的This 此时为 window  object.arrowCallMethod() 

物件内的闭包

  const name = '全域'  const object = {    name: 'Object 区域',    callMethod: function () {      const name = '区域'      return function () {        console.log(this.name) // '全域'      }    },    callMethod2: function () {      const name = '区域'      const that = this      return function () {        console.log(that.name) // '区域'      }    }  }  // 分解成 object.callMethod() 得到 Function  // 该 Function 则在 window 的环境下执行  object.callMethod()()  // that 指向 object 并保存在闭包中  // 执行内部函式,找不到本层that向上找至 callMethod2中的that  object.callMethod2()()

题目练习

const obj = {  a(){    function b(){ console.log(this); }    b();  }}obj.a(); // window (执行环境为 window)
const obj = {  a(){ console.log(this) }}// 物件调用该Function执行obj.a() // objconst b = obj.ab() // 直接执行、window
function a(){ console.log(this) }const obj = {}obj.a = aobj.a() // obj
const obj = {  a() {    console.log(this) // obj    function b() {       console.log(this) // window    }    b() // 直接执行的  }}obj.a()
function a(){  console.log(this) // e.currentTarget}const obj = {a}btn.addEventListener('click', obj.a)
function a(){  console.log(this) // window}const obj = {  b(){    // a 函式属于直接执行    return function (){ a() }  }}btn.addEventListener('click', obj.b())
const obj = {  b(){    // e.currentTarget    return function (){ console.log(this) }  }}// obj.b() 等同于 console.log(this)btn.addEventListener('click', obj.b())
// e.currentTargetfunction a() { console.log(this) }const obj  = { b(){ return a } }btn.addEventListener('click', obj.b())

箭头函式题目

const a  = () => {  // this会去找外层的this  console.log(this) // window}btn.addEventListener('click', a)
const obj = {  a: () => {    // window    console.log(this)  }}obj.a()
function a() {  const b = () => {    console.log(this) // window  }  b() // 直接执行}btn.addEventListener('click', a)

此题重要

function a() {  // 此this作为 DOM事件监听因此为 e.currentTarget  console.log(this)   const b = () => {    // 箭头函式不产this 指向外层 e.currentTarget    console.log(this)   }  b() // 直接执行}btn.addEventListener('click', a)

参考资料

六角 This
OBKoro1's Blog
Kanboo
直播学程式


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章