javascript中的this学习总结

57 阅读2分钟

通过学习,this使用有如下情况:

一、直接调用其中有this的函数

function foo(){
    var a = 1 ;
    console.log(this.a);    // 10
}
var a = 10;
foo();

直接调用函数,这个函数中的this代表全局对象window.

二、一个对象调用有this的函数

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

obj.foo();            // 10       

一个对象调用这个函数,这个函数中的this代表调用者,也就是上例中的obj。如果是链性的关系,比如 xx.yy.obj.foo();, 上下文取函数的直接上级,即紧挨着的那个,或者说对象链的最后一个。

三、单独使用 this

单独使用 this,它指向全局对象 window:

var x = this;
console.log(x);     //window

三、call apply bind这些方法可以显式地设置函数执行时的 this 值。

function foo(xx){    
    console.log(this.a + xx);
}
var obj = {
    a : 10            //去掉里面的foo
}
foo.call(obj,10);        // 20

call 方法接受多个参数,第一个参数指定 this 的值,后续参数是传给函数的参数。也就是说上例中foo函数中的this代表(指向)obj。
apply方法接受多个参数,第一个参数指定 this 的值,第二个参数必须是数组,这个数组代表传给函数的参数列表,除了是数组其它功能与call类似。

function foo(){
    console.log(this.a);
}
var obj = { a : 10 };

foo = foo.bind(obj);
foo();                    // 10

bind只有一个参数,且不会立刻执行,将this指向(绑定)这个参数,并将绑定好的函数返回。

四、new

function Person(name) {
    this.name = name;
}

const person = new Person('Bob');
console.log(person.name); // 输出 'Bob'

当使用 new 关键字调用构造函数时,this 指向新创建的实例对象。注意函数名与new对象名相同。
特别注意 : 如果原函数返回一个对象类型,那么将无法返回新对象,你将丢失绑定this的新对象,例:

function foo(){
    this.a = 10;
    return new String("捣蛋鬼");
}
var obj = new foo();
console.log(obj.a);       // undefined
console.log(obj);         // "捣蛋鬼"

五、箭头函数的this

箭头函数不会创建自己的 this,它会捕获其所在的上下文的 this 值。箭头函数的this绑定无法被修改。

var people = {
    Name: "海洋饼干",
    getName : function(){
        return ()=>{
            console.log(this.Name);
        }
    }
};
var bar = people.getName(); //获得一个永远指向people的函数,不用想this了,岂不是美滋滋?

bar();    // 海洋饼干   

再看一段代码:

var obj= {
    that : this,
    bar : function(){
        return ()=>{
            console.log(this);
        }
    },
    baz : ()=>{
        console.log(this);
    }
}
console.log(obj.that);  // window
obj.bar()();            // obj
obj.baz();              // window
  1. 我们先要搞清楚一点,obj的当前作用域是window,如 obj.that === window。
  2. 如果不用function(function有自己的函数作用域)将其包裹起来,那么默认绑定的父级作用域就是window。
  3. 用function包裹的目的就是将箭头函数绑定到当前的对象上。函数的作用域是当前这个对象,然后箭头函数会自动绑定函数所在作用域的this,即obj。

志远总结:

image.png