JavaScript 的 this 大作战

1、this随运行时变化,谁调用this,this指向谁

this.a = 80;
var test = {
    a: 40,
    init: function(){
        alert(this.a);  // 40
    }
}

test.init();

// test调用, this指向test

2、

this.a = 80;
var test = {
    a: 40,
    init: function(){
        alert(this.a);  // 80
    }
}

var p = test.init;
p();

// 相当于window.p执行了函数体, this指向window

3、this按函数级作用域去找

this.a = 80;
var test = {
    a: 40,
    init: function(){
        function go(){
            alert(this.a);  // 80
        }
        go(); // 在这里执行,go自己调了自己,并且在函数作用域内
    }
}

test.init();

// 没有人调go,this指回了window

4、

this.a = 80;
var test = {
    a: 40,
    init: function(){
        function go(){
            alert(this.a);  // 80
        }
        return go;
    }
}

var p = test.init();
p();  

// this指向window

4、原型链上属性的优先级要弱于构造函数

function go(){
    this.a = 30;
}

go.prototype.a = 40;

go.prototype.test = function() {
    alert(this.a);
}

var m = new go;
m.test();

// 实例调用test, m是实例

5、箭头函数里面根本没有自己的this,而是引用外层的this。箭头函数导致this总是指向函数所在的对象的作用域。

this.a = 20;
var test = {
    a: 40,
    init: () => {
        console.log(this.a);  // 20
    }
};

test.init();

// 指向init函数的对象test的作用域,test的this指向window

6、

this.a = 20;
var test = {
    a: 40,
    init: function(){
        console.log(this.a);  // 20
    }
};

test.init.bind(this)();  // 绑定了this,指向window

// 此题与第5题箭头函数类似
var user = {
    age: 20,
    init: function() {
        console.log(this.age);
    }
};

var data = {age: 18};
var s = user.init.bind(data);
s();  // 18

7、

this.a = 20;
var test = {
    a: 40,
    init: () => {
        // 箭头函数,this指向了window
        console.log(this.a);  // 20
        function go() {
            // 没有构造函数,因此从原型链上找
            console.log(this.a);  // 50
        }
        go.prototype.a = 50;
        return go;
    }
};

new(test.init())();

8、原型链上的优先级要弱于构造函数

this.a = 20;
var test = {
    a: 40,
    init: () => {
        console.log(this.a);   // 20
        function go() {
            this.a = 60;
            console.log(this.a);  // 60
        }
        go.prototype.a = 50;
        return go;
    }
};

var p = test.init();
p();

一些总结:

1、this的使用场景

普通函数中:

      严格模式: undefined

      非严格模式: 全局对象 window

构造函数中:   对象的实例

对象方法:  对象本身

2、构造函数

使用new关键字调用的函数

构造函数可以实例化一个对象

返回值,默认返回类的实例

特殊情况:

      没有返回值

      简单数据类型

      对象类型

3、原型链

每个函数都有一个prototype的对象属性

每个对象都有一个__proto__属性,该属性指向其父类的prototype对象

每个原型对象prototype中都有一个constructor属性,默认指向函数本身

Object.prototype.constructor === Object

Function.prototype.constructor === Function

Object.constructor === Function

猜你喜欢

转载自blog.csdn.net/u010238381/article/details/81122661