广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中 this 的绑定指向规则
  • 393
分享到

JavaScript中 this 的绑定指向规则

2024-04-02 19:04:59 393人浏览 薄情痞子
摘要

目录问题来源this 绑定规则1.默认绑定2.隐式绑定3.显示绑定4.new 绑定5.内置方法6.规则优先级7.规则之外8.实践问题来源 在 js 中,

问题来源

在 js 中,有一个疑惑的点 this, 它的指向问题,存在各种各样的,来看一下,它是如何绑定指向的吧

  • 函数在调用时,javascript 会默认给 this 绑定一个值
  • this 的绑定和定义的位置(编写的位置)没有关系
  • this 的绑定和调用方式以及调用的位置有关系
  • this 是在运行时,动态绑定的

this 绑定规则

1.默认绑定

注意: 严格模式下默认 this 为 undefined ,非严格模式下才是 window

作为独立函数调用时,采用的默认绑定规则:

function foo() {
  console.log(this) // window
}

function test1() {
  console.log(this) // window
  test2()
}
function test2() {
  console.log(this) // window
  test3()
}
function test3() {
  console.log(this) // window
}

test1()

function fn(fnc) {
  fnc()
}

var obj = {
  bar: function () {
    console.log(this)
  }
}

fn(obj.bar) // window 因为`obj.bar`取出的是函数,函数再被独立执行的

2.隐式绑定

作为对象方法调用时,采用隐式绑定规则

function foo() {
  console.log(this)
}

var obj = {
  bar: foo
}
obj.bar() // obj

var obj1 = {
  bar: foo
}
var obj2 = {
  obj1: obj1
}
obj2.obj1.bar() // obj1

var obj3 = {
  foo: foo
}
var bar = obj1.foo
// 取出函数,独立调用了
bar() // window

3.显示绑定

使用 call、apply、bind 进行绑定

function foo() {
  console.log(this)
}

// bind
var obj = {
  name: 'jpliu'
}
var bar = foo.bind(obj)
bar() // obj

// call/apply
foo.call(window) // window
foo.call({ name: 'jpliu' }) // {name: 'jpliu'}
foo.call(123) // Number对象的123     Number {123}
foo.apply('123') // String 对象的'123'  String {'123'}

4.new 绑定

通过 new 关键字实例化对象的时候,绑定为实例化的对象

function Person(name) {
  console.log(this) // Person {}
  this.name = name // Person { name: 'jpliu' }
}
var p = new Person('jpliu')
console.log(p)

5.内置方法

// 其实算是隐式绑定,因为这些方法都是 `window`的
window.setTimeout(function () {
  // 这里或许没这么简单,这个是回调函数,与隐式绑定,没啥关系,这里是浏览器实现的黑盒
  // 在 v8 中,有一个测试用例,模拟,是采用 call 绑定的,this是指向的 window
  // 所以这个看具体如何实现
  console.log(this) // window
}, 2000)

// 2.监听点击
const boxDiv = document.querySelector('.box')
// 隐式绑定 `boxDiv` 的`onclick` 方法触发
boxDiv.onclick = function () {
  console.log(this)
}
// `addEventListener`的`this`是隐式绑定
// 当`callback`的`this`没有显示绑定时
// 使用`bind`显示绑定`addEventListener`的`this`
boxDiv.addEventListener('click', function () {
  console.log(this)
})
boxDiv.addEventListener('click', function () {
  console.log(this)
})
boxDiv.addEventListener('click', function () {
  console.log(this)
})

// 3.数组.forEach/map/filter/find
// 可以通过第二个参数绑定回调函数的`this`
var names = ['abc', 'cba', 'nba']
names.forEach(function (item) {
  console.log(item, this)
}, 'abc')
names.map(function (item) {
  console.log(item, this)
}, 'cba')

6.规则优先级

1.默认规则的优先级最低

2.显示绑定优先级高于隐式绑定

function foo() {
  console.log(this)
}

var obj = {
  name: 'obj',
  foo: foo.bind('aaa')
}

// [String: 'aaa']
obj.foo()

3.new 绑定优先级高于隐式绑定

var obj = {
  name: 'obj',
  foo: function () {
    console.log(this)
  }
}

// new的优先级高于隐式绑定
// foo {}
var f = new obj.foo()

4.new 绑定优先级高于 bind

  • new 绑定和 call、apply 是不允许同时使用的,所以不存在谁的优先级更高
  • new 绑定可以和 bind 一起使用,new 绑定优先级更高
function foo() {
  console.log(this)
}
var bar = foo.bind('aaa')
// foo {} 不是 [String: 'aaa']
var obj = new bar()

7.规则之外

1.null 或者 undefined

// 非严格模式下
// apply/call/bind: 当传入null/undefined时, 自动将this绑定成全局对象
foo.apply(null)
foo.apply(undefined)

var bar = foo.bind(null)
bar()

// 严格模式下,就是 `null/undefined`

2.间接函数引用

var obj1 = {
  name: 'obj1',
  foo: function () {
    console.log(this)
  }
}

var obj2 = {
  name: 'obj2'
}

// 这里是取出了obj1.foo函数,赋值给了obj2.bar
// = 运算法的返回值,就是右侧的值, ob1.foo 的函数定义
// 相当于取出函数,然后独立调用, 所以指向 window
;(obj2.bar = obj1.foo)()

3.箭头函数,箭头函数是无法使用 bind/call/apply 绑定 this 的,箭头函数的 this 是定义的时候所处的上下文环境,无法变更,属于静态 this, 而不是动态绑定的

8.实践

var name = 'window'

var person = {
  name: 'person',
  sayName: function () {
    console.log(this.name)
  }
}

function sayName() {
  var sss = person.sayName
  sss() // window: 独立函数调用
  person.sayName() // person: 隐式调用
  person.sayName() // person: 隐式调用
  ;(b = person.sayName)() // window: 赋值表达式(独立函数调用), 使用 = 号运算符之后,返回了 person.sayName 这个函数方法,后续调用,跟 person 无关
}
sayName()
var name = 'window'

var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = { name: 'person2' }

// person1.foo1(); // person1(隐式绑定)
// person1.foo1.call(person2); // person2(显示绑定优先级大于隐式绑定)

// person1.foo2(); // window(不绑定作用域,上层作用域是全局)
// person1.foo2.call(person2); // window

// person1.foo3()(); // window(独立函数调用)
// person1.foo3.call(person2)(); // window(独立函数调用)
// person1.foo3().call(person2); // person2(最终调用返回函数式, 使用的是显示绑定)

// person1.foo4()(); // person1(箭头函数不绑定this, 上层作用域this是person1)
// person1.foo4.call(person2)(); // person2(上层作用域被显示的绑定了一个person2)
// person1.foo4().call(person2); // person1(上层找到person1)
var name = 'window'

function Person(name) {
  this.name = name
  ;(this.foo1 = function () {
    console.log(this.name)
  }),
    (this.foo2 = () => console.log(this.name)),
    (this.foo3 = function () {
      return function () {
        console.log(this.name)
      }
    }),
    (this.foo4 = function () {
      return () => {
        console.log(this.name)
      }
    })
}

var person1 = new Person('person1')
var person2 = new Person('person2')

person1.foo1() // person1
person1.foo1.call(person2) // person2(显示高于隐式绑定)

person1.foo2() // person1 (上层作用域中的this是person1)
person1.foo2.call(person2) // person1 (上层作用域中的this是person1)

person1.foo3()() // window(独立函数调用)
person1.foo3.call(person2)() // window
person1.foo3().call(person2) // person2

person1.foo4()() // person1
person1.foo4.call(person2)() // person2
person1.foo4().call(person2) // person1
var name = 'window'
function Person(name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}

var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()() // window
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2

person1.obj.foo2()() // obj
person1.obj.foo2.call(person2)() // person2
person1.obj.foo2().call(person2) // obj

到此这篇关于JavaScript中 this 的绑定规则的文章就介绍到这了,更多相关JS this 绑定规则内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript中 this 的绑定指向规则

本文链接: https://www.lsjlt.com/news/150690.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript中 this 的绑定指向规则
    目录问题来源this 绑定规则1.默认绑定2.隐式绑定3.显示绑定4.new 绑定5.内置方法6.规则优先级7.规则之外8.实践问题来源 在 js 中,...
    99+
    2022-11-13
  • JavaScript 中的 this 绑定规则详解
    目录前言1. 关于 this 的简单介绍2. 为什么使用 this?3. 关于this 的常见的误解4. this 的绑定规则4.1 默认绑定4.2 隐式绑定4.3 显式绑定4.4 ...
    99+
    2023-02-14
    JavaScript中的this绑定规则 JavaScript中的this关键字 JS中this的4种绑定规则
  • JavaScript中this有几种绑定规则
    这篇“JavaScript中this有几种绑定规则”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看...
    99+
    2022-10-19
  • JavaScript中this的绑定规则是怎样的
    JavaScript中this的绑定规则是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。对于 JavaScript 新手来说,this ...
    99+
    2022-10-19
  • 一文搞懂JavaScript中的this绑定规则
    目录前言  this四大绑定规则一.默认绑定二.隐式绑定三.new绑定四.显示绑定绑定规则优先级面试题题1题2题3题4前言  首先我们来看一个示例。定义...
    99+
    2022-11-13
  • JavaScript中this绑定规则的示例分析
    这篇文章主要介绍JavaScript中this绑定规则的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、this 的绑定规则this 一共有 4 中绑定规则,接下来一一介绍...
    99+
    2022-10-19
  • JavaScript this绑定与this指向问题如何解决
    本篇内容主要讲解“JavaScript this绑定与this指向问题如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript this绑定与this指向问...
    99+
    2023-07-05
  • this的四个绑定规则是什么
    这篇文章主要介绍“this的四个绑定规则是什么”,在日常操作中,相信很多人在this的四个绑定规则是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”this的四个绑定规则是什么”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-04
  • 带你详解 this 的四个绑定规则
    实际上,JavaScript 中 this 的机制并没有那么先进,但是开发者往往会把理解过程复杂化, 毫无疑问,在缺乏清晰认识的情况下,this 对你来说完全就是一种魔法。2. 为什么使用 this?const obj = { titl...
    99+
    2022-11-22
    javascript this
  • JavaScriptthis绑定与this指向问题的解析
    目录一、this 绑定怎么理解 this?this 是如何绑定的?this 绑定优先级二、this 指向判断准则判断顺序常见的指向问题三、改变 this 指向有四种方式变量保存 th...
    99+
    2023-02-27
    JavaScript this绑定 JavaScript this指向
  • JavaScript this指向绑定方式及不适用情况详解
    目录前言问题复现调用位置默认绑定隐式绑定显式绑定new 绑定不适用的情况总结前言 JavaScript 中的 this 指向问题对于 web 前端入行不深的人来说是个比较复杂的问题。...
    99+
    2023-05-15
    JavaScript this指向 JavaScript this绑定方式
  • JavaScript this指向绑定方式及不适用情况是什么
    这篇文章主要讲解了“JavaScript this指向绑定方式及不适用情况是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript this指向绑定方式及...
    99+
    2023-07-06
  • javascript中的this指向什么
    这篇文章主要介绍“javascript中的this指向什么”,在日常操作中,相信很多人在javascript中的this指向什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2022-10-19
  • JavaScript中this的错误认识和绑定规则以及常见问题是怎样的
    JavaScript中this的错误认识和绑定规则以及常见问题是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。相信 Ja...
    99+
    2022-10-19
  • React中事件绑定this指向三种方法的实现
    1.箭头函数 1.利用箭头函数自身不绑定this的特点; 2.render()方法中的this为组件实例,可以获取到setState(); class App extends ...
    99+
    2022-11-12
  • 详解JavaScript中的this硬绑定
    目录一、this显示绑定二、硬绑定一、this显示绑定 this显示绑定,顾名思义,它有别于this的隐式绑定,而隐式绑定必须要求一个对象内部包含一个指向某个函数的属性(或者某个对象...
    99+
    2022-11-13
  • JavaScript中的this关键词指向
    目录1、es5中的this的指向2、es6中的this1、es5中的this的指向 this是JavaScript的一个关键字,他是函数执行过程中,自动生成的一个内部对象,指当前的对...
    99+
    2022-11-13
  • JavaScript中的this指向和自定义属性详解
    目录1.this关键字2.自定义属性3.综合案例1:tab选项卡的实现附录总结1.this关键字 this指向的是当前元素 全局函数中的this指向window对象 代码中声明...
    99+
    2022-11-12
  • JavaScript中this指向的示例分析
    小编给大家分享一下JavaScript中this指向的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!this先看代码:方法中function t...
    99+
    2023-06-25
  • JavaScript中的this指向问题详解
    前言 相信我,只要记住本文的 7️⃣ 步口诀,就能彻底掌握 JS 中的 this 指向。 先念口诀:箭头函数、new、bind、apply 和 call、欧...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作