jsにおけるthisの使い方
12865 ワード
nodejsとbrowserの中でthisの比較
nodejsのグローバルオブジェクトはglobalで、jsファイルはモジュールであり、モジュール内部にモジュールの役割領域を形成し、定義された変数はこのモジュールでのみ使用できます.globalオブジェクトまたはmodule.exportを使用して、複数のモジュール間で変数を共有できます.
関数文脈では、nodejsとbrowserでは、thisの指し示す原理は基本的に同じで、以下のnodejsでテストします. thisが明確にされていない場合、デフォルトはグローバルオブジェクト を指す.矢印関数(arrow function)矢印関数のthisは、参照関数が定義される場合のコンテキストを指し、クローズドが形成される. オブジェクトの方法関数をオブジェクトとして呼び出す場合、thisは、この方法を呼び出すオブジェクトを指す. 構築関数 newキーワードはデフォルトでfunctionのthisオブジェクトに戻ります.オブジェクトのプロトタイプに オブジェクトはprototype上のメソッドを呼び出すことができます.thisは現在のオブジェクトを指しています.オブジェクト自体の方法と似ています.これはjsプロトタイプチェーン継承の特性です.
主に対象法、一般関数、矢印関数におけるthisの指向を考慮します.オブジェクトメソッドによって呼び出しと呼び出しは異なる場合があります.
nodejsのグローバルオブジェクトはglobalで、jsファイルはモジュールであり、モジュール内部にモジュールの役割領域を形成し、定義された変数はこのモジュールでのみ使用できます.globalオブジェクトまたはmodule.exportを使用して、複数のモジュール間で変数を共有できます.
// this module.exports
this === module.exports // true
this === exports // true
this // {}
// x.js
this.a = 1
exports.b = 2
module.exports.c = 3
// y.js
const {a, b, c} = require('./x.js')
browser環境のグローバルオブジェクトはwindowで、nodejsのglobalに相当します.モジュールの役割領域が存在しないため、nodejsとbrowserでthisの値が異なります.// (global context) this window
this === window // true
変数宣言var a = 1
let b = 2
const c = 3
d = 4
// nodejs ,a b c
global.a // undefined
global.b // undefined
global.c // undefined
global.d // 4, d , global
// browser , var , window , (legacy)
this.a // 1
this.d // 4
// es6 let const, window
this.b // undefined
this.c // undefined
nodejsとbrowserのいずれもthisに対して直接値を割り当てることができません.this = 1 // Invalid left-hand side in assignment
関数コンテキスト(function context)でthisの使い方関数文脈では、nodejsとbrowserでは、thisの指し示す原理は基本的に同じで、以下のnodejsでテストします.
function foo() {
return this
}
// , this ,
foo() === global // true in node
foo() === window // true in browser
function foo() {
'use strict'
return this
}
// , this
foo() // undefined
this.a = 1
let foo = (b) => this.a + b
foo(2) // 3
foo.call({a: 2}, 2) // 3,call this
let f1 = foo.bind({a: 3})
f1(2) // 3,bind this
this.a = 2
foo() // 4,
let obj = {
x: 1,
f: getX,
y: {
x: 2,
g: getX
}
}
// getX obj ,
function getX() {
return this.x
}
obj.f() // 1
getX.call(obj) // 1
obj.y.g() // 2
getX.call(obj.y) // 2
function Foo() {
this.a = 1
}
// new {a: 1}
let f = new Foo()
構築関数がオブジェクトに戻ると、newはオブジェクトに戻り、定義されたthisオブジェクトを返さない.function Foo() {
this.a = 1
return {b: 2} // {b: 2}
return [1, 2] // [1, 2]
return new Number(2) // [Number 2]
return null // {a: 1}
return undefined // {a: 1}
return // {a: 1}
return 1 // {a: 1}
return 'abc' // {a: 1}
}
function Foo(a, b) {
this.a = a
this.b = b
}
Foo.prototype.add = function () {
console.log(this.a + this.b)
}
Foo.prototype.delayAdd = function () {
setTimeout(this.add, 500)
}
let foo = new Foo(1, 2)
foo.add() // 3, ,this foo
一つの方法を追加しますFoo.prototype.delayAdd = function () {
setTimeout(this.add, 500)
}
let foo = new Foo(1, 2)
foo.delayAdd() // undefined,
// :delayAdd
Foo.prototype.delayAdd = function () {
// this foo
setTimeout(function () {
// : nodejs Timeout , setTimeout()
// browse this window
return this.a + this.b
}, 500)
}
// bind this
Foo.prototype.delayAdd = function () {
setTimeout(this.add.bind(this), 500)
}
foo.delayAdd() // 3,
実例分析主に対象法、一般関数、矢印関数におけるthisの指向を考慮します.オブジェクトメソッドによって呼び出しと呼び出しは異なる場合があります.
let o = {
foo: () => this,
bar: function () {
return this
},
baz: function () {
return () => this
},
qux: () => {
return () => this
},
one: function () {
return function () {
return this
}
},
two: () => {
return function () {
return this
}
}
}
fooは矢印関数を用いて定義されるオブジェクト方法であり、文脈ではthisがmodule.exportsを指し、クローズドされている.o.foo() === module.exports // true
o.qux() === module.exports // true
//
let foo = () => {
return () => {
return () => this
}
}
foo()()() === exports // true
barは、一般関数で定義されたオブジェクト方法で、内部thisは現在のオブジェクトoを指します.矢印関数が定義されているときは、閉じられたパケットが形成されます.thisはコンテキストのthisを指します.o.bar() === o // true
o.baz()() === o // true
oneとtwoの中でthisは直接的に対象の方法の中に位置していません.他の方法でthisの指向を変えて、globalを指します.o.one()() === global // true
o.two()() === global // true
先に値を割り当ててから呼び出すと、結果が違ってきます.let b = o.baz
b()() === global // true
//
let b = function(){
return () => this
}
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this