小白快速入门:JavaScript中的this

JavaScript中的this

你真的了解this吗?

第一次写文章,如有错误还请指教。
很多人可能会对javascript中的this感到困惑,但其实this可能比你想象中的要简单ヽミ ´∀`ミノ<

开门见山

要真正的了解this,我们应该先去了解一下关于this的绑定机制。

this一共有四种绑定机制

  • 默认绑定
  • 上下文绑定
  • new绑定
  • 硬绑定
    你可以把这四条规则看作this的天条,this到底代表了什么(也就是绑定了什么)和他们密切相关。

默认绑定

this默认绑定到javascript中windows全局对象。

除非该绑定被切断

function test() {
    var a = 5
    console.log(a)
}
var a = 10

test()      //输出 10

是不是有点疑惑?我们再看一个代码片段

function test() {
    var a = 5
    console.log(a)
}
var a = 10

test()      //输出 5

这个时候我们把this输出

function test() {
    var a = 5
    console.log(a)
    console.log(this.a)
    console.log(this)

    //分别输出
    //      5
    //      10
    //      Window 
}
var a = 10
test() 

我们开始解释这3个输出:

  1. console.log(a)

    这个输出,其实没什么好疑惑的,是根据变量的作用域来获取到了function里的a的值
  2. console.log(this.a)

    这里我们再看一次this的默认绑定

    this默认绑定到javascript中windows全局对象。

而且在全局作用域中声明的变量默认绑定到windows,所以this.a指的就是var a = 10 在全局定义的那个a
而且第三个输出证实了这一点
this就是windows

注意在严格模式中,默认情况下this不会绑定到windows

同时我们得出了一个别的结论

this指向函数的作用域,这是一个天大的误解。

我们必须清楚this在任何的情况下都不指向函数的词法作用域

上下文绑定

理解上下文绑定主要注意是否是对象调用的函数

var obj = {
    a: 2
}

obj是一个对象

function foo() {
    console.log(this.a)
}

foo是一个声明的函数

而当一个函数属于一个对象的时候

obj.foo = foo

此时调用obj.foo()

输出 2

this在对象中的指向只会受到最后一层对象的影响

function foo() {
    console.log(this.a)
}

var obj2 = {
    a: 42,
    foo: foo
}

var obj1 = {
    a: 2,
    obj2: obj2
}

obj1.obj2.foo()

//输出  42

所以关于上下文绑定一定要注意是否是对象调用的函数

上下文绑定会切断this的默认绑定

new绑定

使用new调用函数,或者说发生构造调用时,会自动执行下面的操作

  1. 创建一个全新的对象。
  2. 这个对象会被执行[[原型]]链接。
  3. 这个新对象会绑定到函数调用的this
  4. 如果这个函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。
function foo(a) {
    this.a = a
}
var bar = new foo(2)
console.log(bar.a)  
// 输出     2

使用new来调用foo(..)时,我们会构建一个新的对象并把它绑定到foo(..)调用的this上。

以上引用于 你不知道的javascript(上)

new绑定会切断默认绑定

硬绑定

通俗的说就是为function中出现的this手动的指定一个对象

javascript中提供了

call bind等常用的用于手动明确的指定this的函数

硬绑定也会切断默认绑定

总结

绑定的优先级

new绑定>硬绑定>上下文绑定>默认绑定

默认绑定是可以被另外三种绑定切断的

应用

判断this的方法:
1.函数是否在new中调用(new绑定)?
如果是的话this绑定的是新创建的对象。

var bar = new foo()

2.函数是否通过call,apply(显式绑定)或者硬绑定调用?
如果是的话。this绑定的是指定的对象。

var bar = new foo.call(obj2)

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

var bar = obj1.foo()

4.如果都不是的话,使用默认绑定。如果在严格模式下,
就绑定到undefined,否则绑定到全局对象。

var bar = foo()

本文结束,以上部分内容出自你不知道的javascript(上)

猜你喜欢

转载自www.cnblogs.com/lbzli/p/11503947.html