原生JS的this绑定

         首先看一个示例。定义一个函数,用三种不同的方式调用,会产生三种不同的结果

function foo(){
    console.log(this);
}
foo() //window
let obj ={
   name:'sss',
   foo:foo
}
obj.foo()//{name:'sss',foo:function}
foo.call("abc")  // 生成包装类型对象,String {'abc'}

        一个函数调用方式不同导致this指向也不相同,因为在JavaScript中函数的this是动态绑定的(箭头函数除外)。大概总结四点

        1、函数在调用时,JavaScript会默认给this绑定一个值。

        2、this的绑定与编写的位置没有关系

        3、this的绑定与调用的方式以及调用的位置有关

        4、this的绑定是在运行时进行的

This绑定指向的四大绑定规则

        一、默认绑定

        独立函数调用的就是默认绑定,就是函数没有绑定到某个对象上进行调用,默认返回window(但是在严格模式中返回undefined)举下面三个例子就明白了

function foo(){
    console.log(this); 
}
foo()  // 独立函数调用 
let obj ={
    name:'sss',
     bar:function(){
         console.log(this);
    }
}
let ff = obj.bar

ff() // 函数在对象中,但是独立函数独立函数调用

// 高阶函数
function test(fn){
     fn()
}
test(obj.bar) //相当于fn=obj.bar fn() 所以还是独立函数调用



//以上三个输出 都是独立函数调用 因此都是指向Window
//以上三个输出 都是独立函数调用 因此都是指向Window
//以上三个输出 都是独立函数调用 因此都是指向Window

       二、隐式绑定

        在调用位置中,通过对象来发起的调用会返回调用它的那个对象,举个例子

let obj ={
    name:'sss',
     bar:function(){
         console.log(this);
    }
}
obj.bar() // 通过对象调用,结果是指向 obj

        三、new 绑定

        JavaScript中的函数也可以当作一个构造函数来使用,也就是通过new关键字,new关键字其实做了四步,首先创建构造一个全新的对象,然后这个对象执行[prototype]连接,然后将这个新对象绑定在this上,没有显示其他返回对象时候,最后返回这个新对象,同样 通过代码举个例子

function person(name) {
    this.name =name
    console.log(this);
}
new person('sss') // person{name:'sss'}

        四、显式绑定

        相当于强制绑定,使用call,bind,apply等一系列方法进行强制绑定;通过改变this的指向,举个例子举个例子就明白了

function foo(){
    console.log(this);
}
let obj ={
    name:'sss'
}
// 此时我们希望this指向obj 如果是正常情况下该这么指向呢
// 1
obj.foo = foo
obj.foo() // obj
// 但是我们希望直接绑定 就可以通过call 来进行显式绑定
foo.call(obj) //obj
foo.call("123") //"123"
foo.call(123) //123

        既然说到了call,bind,apply,那就简单说一下他们的相同点和不同点

        相同点:1、都是改变this指向的,

                       2、第一个参数都是this要指向的对象,

                       3、都可以利用后续参数传参

        不同点:1、call和bind的参数是依次传参,也就是一一对应的,

                       2、apply只有两个参数,而且第二个参数还得是数组

                       3、call和apply都是直接对函数进行调用,而bind方法返回的仍然是一个函数

但是这四种绑定规则也存在优先级,同时使用也存在谁先谁后,通过四个方面去判断

        1、函数是否在new中调用(new绑定)?如果是的话this绑定的就是新创建的对象;

        2、函数是否通过call、apply、bind调用(显示绑定)?如果是的话,this绑定的是指定的对象;

        3、函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this绑定的是那个上下文对象;

        4、如果都不是的话,使用默认绑定,绑定到全局对象(严格模式绑定到undefined)

        通过上面的1、2、3、4的优先级来判断         

还有就是箭头函数

箭头函数与普通函数的区别:

1.普通函数this 指向 为方法调用的对象;可以通过bind,call,apply改变this指向 箭头函数不会创建自己的this,只会从自己的作用域链的上一层继承this;不可修改this指向

2.箭头函数没有原型

3.箭头函数不能绑定arguments,取而代之用rest参数...解决

4.箭头函数是匿名函数,不能作为构造函数,不能使用new 普通函数可以用于构造函数创建实例

5.箭头函数没有super

6.箭头函数比函数表达式更简洁

在箭头函数中:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值