this

**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) //=>Number
foo.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,否则绑定到全局对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值