以下内容来自《你不晓得的js》读书笔记

this提供了一种更优雅的形式来隐式“传递”一个对象援用,因而能够将API设计得更加简洁并且易于复用。

this与函数的调用地位无关。

一、 this的绑定规定

  • 默认绑定
  • 隐式绑定
  • 显示绑定
  • new绑定

1. 默认绑定:即独立函数调用,this会绑定到全局对象上(非严格模式)

function foo(){    console.log(this.a); // 2}var a=2;foo();
留神:对于默认绑定来说,决定this绑定对象的并不是调用地位是否处于严格模式,而是**函数体是否处于严格模式**。如果函数体处于严格模式,this会被绑定到undefined,否则this会被绑定到全局对象。

2. 隐式绑定:调用地位是否有上下文对象,this会被绑定到这个上下文对象。

function foo(){    console.log(this.a);}var obj={    a: 2,    foo: foo}obj.foo();// 2
留神:1.对象属性援用链中只有上一层或者说最初一层在调用地位中起作用,即obj.obj2.foo(),那么foo中的this被绑定到了obj2上。2.隐式失落:被隐式绑定的函数会失落绑定对象,也就是说它会利用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。    (1)将函数赋值给其余变量    (2)函数作为另外一个函数的参数传递进去(严格意义上也属于(1))    function foo(){        console.log(this.a);// 42,产生了隐式失落    }    var obj={        a: 2,        foo: foo    }    var a = 42;    var foo2=obj.foo;    foo2();

3. 显示绑定:能够间接指定this的绑定对象

  • call、apply
function foo(){    console.log(this.a);}var obj={    a: 2}foo.call(obj);// 2
  • 以下两种形式可解决失落绑定问题:

    • 硬绑定:bind(硬绑定后的this不能再次批改)
    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);// 2, 3console.log(b);// 5
    • API调用的“上下文”:第三方库的许多函数,以及JavaScript语言和宿主环境中许多新的内置函数,都提供了一个可选的参数,通常被称为“上下文”

4. new绑定:在JavaScript中,构造函数只是一些应用new操作符时被调用的一般函数。

  • 创立(或者说结构)一个全新的对象。
  • 这个新对象会被执行[[Prototype]]连贯。
  • 这个新对象会绑定到函数调用的this。
  • 如果函数没有返回其余对象,那么new表达式中的函数调用会主动返回这个新对象。

**留神:this绑定的优先级:
new绑定 > 显示绑定 > 隐式绑定 > 默认绑定**

5. 箭头函数:不会应用以上四条规范的绑定规定,依据以后的词法作用域来决定this

二、 绑定例外

  • 被疏忽的this:如果你把null或者undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被疏忽,理论利用的是默认绑定规定。
  • 间接援用:你有可能(无意或者无心地)创立一个函数的“间接援用”,在这种状况下,调用这个函数会利用默认绑定规定。
function foo(){    console.log(this.a);}var a = 2;var o={a: 3, foo:foo};var p={a:4};o.foo();//3(p.foo=o.foo)();// 2// 赋值表达式p.foo = o.foo的返回值是指标函数的援用,因而调用地位是foo()而不是p.foo()或者o.foo()。依据咱们之前说过的,这里会利用默认绑定。
  • 软绑定:和硬绑定雷同的成果,同时保留隐式绑定或者显式绑定批改this的能力。

如果this绑定到全局对象或者undefined,那就把指定的默认对象obj绑定到this,否则不会批改this

if(!Function.prototype.softBind){    Function.prototype.softBind=function(obj){        var fn=this;        var curried=[].slice.call(arguments, 1);        var bound=function(){            return fn.apply(            (!this || this === (window || global)) ? obj : this,            curried.concat.apply(curried, arguments)            )        };        bound.prototype=Object.create(fn.prototype);        return bound;    }}

心愿大家能继续关注哦,留一些个人信息不便大家找到我哦。知乎 github
附上集体公众号哦,心愿大家前来骚扰(也会常常写一些随笔来记录生存,毕竟人生漫漫)