js:this

240 阅读2分钟

为什么要有this?

  function identify() {
        return this.name
    }
    function speak() {
        var getting = 'hello,' + identify.call(this)
        console.log(getting)
    }
    var me = {
        name: 'yao'
    }
    var you = {
        name: 'xixi'
    }
    console.log(identify.call(me))
    console.log(identify.call(you))
    speak.call(me)
    speak.call(you)

这段代码可以在不同的上下文对象(me和you)中重复使用函数,不用针对每个对象编写不同版本的函数。

如果不使用this,就需要给函数显示传入一个上下文对象。

    function identify(cont) {
        return cont.name
    }
    function speak(cont) {
        var getting = 'hello' + identify(cont)
        console.log(getting)
    }
    var me = {
        name: 'yao'
    }
    var you = {
        name: 'xixi'
    }
    console.log(identify(me))
    speak(you)
this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

判断this指向(ಥ_ಥ)

独立函数调用时:在严格模式下绑定到undefined,否则绑定到全局对象。

function foo (){
console.log(this.a)
}
var a=2
foo()//2

由上下文对象调用,绑定到那个上下文对象。

function foo(){
console.log(this.a)
}
var obj={
a:2,
foo:foo
}
obj.foo()//2
function foo(){
console.log(this.a)
}
var obj1={
a:52,
obj2:obj2
}
var obj2={
a:25,
foo:foo
}

obj1.obj2.foo()//25

foo()最后实在obj2上调用的所以最后打印的也就是25。

由new调用,绑定到新创建的对象。

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

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

由call或者apply、bind调用,绑定到指定的对象。

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

通过foo.call()可以在调用foo时强制把它的this绑定到obj上。

call、apply、bind都可以改变this的指向,call()和apply()方法基本类似都是,调用一个函数,其具有一个指定的this值,apply的第2个参数作为一个数组或类数组的对象提供参数。call则是接受得是若干个参数列表。

func.apply(函数运行时指定的this值,[参数传给fun函数])

apply()

var a={
name:'',
fn:function(a,b){
console.log(a+b)
}
}
var b=a.fn
b.apply(a,[1,2])//3

func.apply(函数运行时指定的this值,参数传给fun函数)

call()

var a={
name:'',
fn:function(a,b){
console.log(a+b)
}
}
var b=a.fn
b.call(a,1,2)//3

bind()方法在创建一个新的函数,需要手动调用。

var a={
name:'',
fn:function(a,b){
console.log(a+b)
}
}
var b=a.fn
b.bind(a,1,2)()//3

箭头函数

箭头函数的this始终指向它的词法作用域,也就是指向函数定义时,并非执行时。

var name='yao'
var a={
name:'you',
func1:function(){
console.log(this.name)
},
func2:function(){
setTimeout(()=>{
this.func1()
},1000)
}
}

a.func2() //you