this

Node.js this

this 是什麽

  • this 是 JavaScript 的一个关键字。
  • this 是 function 执行时,自动生成的一个内部物件。
  • 随着 function 执行场合的不同,this 所指向的值,也会有所不同。
  • 在大多数的情况下, this 代表的就是呼叫 function 的物件。
  • 非物件导向底下,要看执行环境有不同预设值
    • node.js : global
    • 浏览器 : window
    • 严格模式 : undefined ( node.js 跟浏览器都一样 )
  • 物件导向中, this 就是 new 出来的 instance
  • DOM 事件绑定时, this 为 绑定的 DOM 物件
  • 单纯在物件底下,this 跟如何呼叫 function 有关
  • 如果是在物件本身上呼叫,this 为物件本身
  • 把 function 抽出来呼叫,this 则为预设值 ( global or window or undefined )
  • arrow function 中,根据外部的 this 是什麽而决定
var obj = {

    func1: function(){
        // 这裡的 this 指的是 func1
        // [func1] is object: true
        console.log( '[func1] is object:', this === obj );

        var func2 = function(){
            // 这裡的 this 指的是 global
            // [func2] is obj:  false
            console.log( '[func2] is obj: ', this === obj );
            // [func2] is global true
            console.log( '[func2] is global', this === global );
        };

        func2();
    }
};

obj.func1();

func1 透过 object 呼叫,所以裡面的 this 指的是 obj 物件本身

func2 直接呼叫,没特别指定的话,指的就是全域变数 global

function 透过物件呼叫及直接呼叫

function func() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: func
};

// undefined
func();
// 2
obj.foo();    

透过物件呼叫,因为裡面的 this 指的会是物件本身,所以能够取的物件的 属性 a 资料

var a = {
    value : 1,
    getVal: () => this.value
};

var b = {
    value : 2,
    getVal: function () {
        return this.value
    }
}

// undefined
console.log(a.getVal());
// 2
console.log(b.getVal());

var c = a.getVal;
var d = b.getVal;

// undefined
console.log(c());
// undefined
console.log(d()); 
function func() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: func
};

// 2
obj.foo();  

var func2 = obj.foo;
// undefined
func2();

func2 参照的对象是 global 所以还是无法存取到 属性 a 资料

变更 this 对象

透过 bind, call, apply 可以变更 this 指定对象

function func() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: func
};

// 2
obj.foo();

var func2 = obj.foo;
// undefined
func2();

let bindFunc2 = func2.bind(obj)
// 2
bindFunc2();
// 2
func2.apply(obj);
// 2
func2.call(obj);

使用 new 会建立属于该函式的物件

function foo(a) {
    this.a = a;
}

var obj = new foo( 123 );
// 123
console.log( obj.a );

this 来源

执行方式 this 指的是
使用 new 建立 被建构的物件
使用 bind, call, apply 传入的物件
function 被呼叫是否存在某物件 存在的物件
其他 全域物件 global (严格模式则为 undefined)

例外状况

箭头函示 arrow function 中的 this

箭头函式当中的 this 绑定的是是定义时的物件,而不是使用时的物件,所以定义当下 this 指的是哪个物件就会是那个物件,不会随着时间改变

Example 1: 一般函式
'use strict';

class Test {
    run() {
        console.log('run: ', this);
        setTimeout(function() {
            console.log('setTimout: ', this);
        }, 1000);
    }
}
const test = new Test();
test.run();
// run: Test {}

// setTimout:  Timeout {
//   _idleTimeout: 1000,
//   _idlePrev: null,
//   _idleNext: null,
//   _idleStart: 43,
//   _onTimeout: [Function (anonymous)],
//   _timerArgs: undefined,
//   _repeat: null,
//   _destroyed: false,
//   [Symbol(refed)]: true,
//   [Symbol(kHasPrimitive)]: false,
//   [Symbol(asyncId)]: 5,
//   [Symbol(triggerId)]: 1
// }
Example 2: 箭头函式
'use strict';

class Test {
    run() {
        console.log('run: ', this);
        setTimeout(() => {
            console.log('setTimout: ', this);
        }, 1000);
    }
}
const test = new Test();
test.run();
// run: Test {}
// setTimout: Test {} ( 一秒后 )

事件监听中的 this

DOM 物件绑定某种事件时,this 会变成绑定的 DOM 元素本身

document.querySeletor('.btn').addEventListener('click', function(){
    console.log(this); // => btn 这个元素
});

参考资料