文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScriptthis绑定与this指向问题的解析

2023-02-27 11:47

关注

一、this 绑定

怎么理解 this?

其实 this 就是一个指针,它指示的就是当前的一个执行环境,可以用来对当前执行环境进行一些操作。

MDN 解释:在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。ES5 引入了 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。

this 是如何绑定的?

每个函数的 this 是在调用时被绑定的,完全取决于函数的调用位置。我们找到函数的调用位置,然后运用以下四种绑定规则来判断函数的 this 指向。

1、默认绑定

函数的 this 会默认绑定到全局对象 window 上,如果在严格模式中,this 绑定到 undefined。

function foo (){
  console.log(this.a)
}
let a = 1
foo() // 1

2、隐式绑定

调用位置是否有上下文对象,或者被某个对象拥有或包含。

function foo(){
  console.log(this.a)
}
let obj = {
  a: 2,
  foo:foo
}
let a = 1
obj.foo(); // 2

function foo(){
  console.log(this.a)
}
let obj1 = {
  a: 2,
  foo: foo
}
let obj2 = {
  a: 3,
  obj1: obj1
}
let a = 1
obj2.obj1.foo(); // 2

3、显式绑定

直接改变 this 指向,绑定到另一个执行环境

function foo(){
  console.log(this.a)
}
let obj = {
  a: 1
}
foo.call(obj)

4、new 绑定

new 出来的函数 this 绑定的是新创建的对象

function Foo(a){
  this.a = a
}
let bar = new Foo(2)
console.log(bar.a) // 2

this 绑定优先级

默认绑定的优先级是最低的

new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定

1、显示绑定 VS 隐式绑定

function foo(){
  console.log(this.a)
}
let obj1 = {
  a: 1,
  foo: foo
}
let obj2 = {
  a: 2
}
console.log(obj1.foo()) // 1
obj1.foo.call(obj2) // 2

通过以上代码我们可以看到 显式绑定 的优先级高于 隐式绑定

2、显示绑定 VS new 绑定

function foo(a){
  this.a = a
}
let obj1 = {
  foo
}
let bar = foo.bind(obj1)
bar(2)
console.log(obj1.a) // 2
let bar2 = new bar(3)
console.log(obj1.a) // 2
console.log(bar2.a) // 3

new 修改了显示绑定 调用 bar 中的 this,所以 new 绑定的优先级高于显式绑定

二、this 指向

判断准则

第一准则:this 永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。(不包含箭头函数)

第二准则:无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象

判断顺序

常见的指向问题

三、改变 this 指向

有四种方式

变量保存 this

var _this = window;
var obj = {
    name:"张三",
    show:function(){
        console.log(this) //obj
        console.log(_this) // window
    }
}
obj.show()

call

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

函数名称.bind(参数1,参数2,a,b,c.....)
    参数1:当前函数的作用域
    参数2:需要传递的参数,参数是一个一个传

function fn(a,b){
    console.log(this,a,b)
}
document.onclick = functioin(){
    fn.call(document,1,2)
}

可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

function Product(name, price) {
  this.name = name;
  this.price = price;
}
function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}
function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

bind

bind 创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

特性就是会有一个返回值,返回值是一个拥有第一个函数作用域的新的函数体

函数名称.bind(参数1,参数2.....)() // 必须调用一下
    参数1:当前函数的作用域
    参数2:需要传递的参数

var obj = {
    name:"张三",
    show:function(val){
        console.log(this) //obj  没有修改前
        console.log(this,1) // document 1     修改后
    }
}
obj.show().bind(document,1)()

MDN:ECMAScript 5 引入了 Function.prototype.bind()。调用 f.bind(someObject) 会创建一个与 f 具有相同函数体和作用域的函数,但是在这个新函数中,this 将永久地被绑定到了 bind 的第一个参数,无论这个函数是如何被调用的。

apply

apply() 方法调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。

函数名称.bind(参数1,[参数2,a,b,c.....])
    参数1:当前函数的作用域
    参数2:需要传递的参数   数组

function fn(a,b,c){
    console.log(this,a,b,c)
}
document.onclick = functioin(){
    fn.apply(document,[1,2,3])
}

call ,apply ,bind 三者的区别

不同点:

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯