this

来源:互联网 发布:什么是键值数据库 编辑:程序博客网 时间:2024/06/05 06:09

**this 是在运行式进行绑定的,并不是在编写是绑定
this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式
this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用**

默认绑定

var a = 'aaa';var obj = {    a: 'bbb'}var fun = {    a: 'ddd',    foo: function(){        (function(){            var a = 'ccc';            console.log(this.a)        })(); //=>aaa        (function(){            console.log(this.a) //=>bbb        }).call(obj);        (function(){            console.log(this.a)  //=>ddd        }).call(fun);        }}fun.foo();//匿名函数内默认this指向window

如果使用严格模式,则不能将全局对象用户默认绑定,因此this会绑定到undefined

function foo(){    "use strict";    console.log(this.a)}var a = 3;foo()  //Uncaught TypeError: Cannot read property 'a' of undefined

隐式绑定

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

隐式绑定的函数会丢失绑定对象

function foo(){    console.log(this.a);}var obj = {    a:2,    foo: foo};var bar = obj.foo;var a ="oops";bar();  //=> 'oops'
function foo(){    console.log(this.a)}function doFoo(fn){    //fn其实引用的是foo    fn(); //调用位置,因为doFoo的作用域中没有变量a,所以往上找到全局变量a='global'}var obj = {    a: 2,    foo: foo}var a = 'global';doFoo(obj.foo) //=>'global'

显示绑定

function foo(){    console.log(this.a)}var obj = {    a: 2}foo.call(obj) //=>2

如果传入的是一个原始值,这个原始值会转换成它的对象形式,这个过程称为“装箱”

function foo(){    console.log(this)}foo.call(2) //=>Numberfoo.call("str") //>String

new绑定
使用new 来调用函数,会自动执行下面的操作
1. 创建一个全新的对象
2. 这个新对象会被执行prototype连接
3. 这个新对象会绑定到函数调用的this
4. 如果函数没有返回其他对象,则new表达式中的函数调用会自动返回这个新对象

function foo(a){    this.a = a;}var bar = new foo(2);console.log(bar.a) //=>2

箭头函数中的this

箭头函数中的this是根据外层(函数或者全局)作用域来决定的,即会继承外层函数调用的this绑定

function foo(){    return (a) => {        console.log(this.a)    }}var obj1 = {    a: 2};var obj2 = {    a: 3}var bar = foo.call(obj1);bar.call(obj2)   //=>2

foo内部创建的箭头函数会捕获调用时foo()的this,由于foo的this绑定到obj1,bar的this也会绑定到obj1,箭头函数的绑定无法被修改

如果要判断一个运行中的函数的this绑定,就需要找到这个函数的直接调用位置,找到之后就可以顺序应用以下四条规则来判断this的指向:

  1. 由new调用?绑定到新创建的对象
  2. 由call、apply或bind调用?绑定到制定对象
  3. 由上下文对象调用?绑定到那个上下文对象
  4. 默认,在严格模式下绑定到undefined,否则绑定到全局对象
原创粉丝点击