LoginSignup
0
0

More than 1 year has passed since last update.

JavaScriptのthisやあれこれ

Posted at

はじめに

初学者です。
基本は備忘録

関数とthis

function fn(a, b) {
  console.log(a, b);
}

fn(1) //結果: 1 undefined
fn(null, 1)//結果 null 1
//2つめだけ使いたい場nullを使う

jsでは同じ関数が2つ以上ある場合後に書いた方が実行される
関数式で宣言するとエラーで教えてくれる

function fn(a, b = 2) { //デフォルト値を設定できる
  console.log(a, b);
}
fn(1, null)// 1 null
fn(1, undefined)// 1 2
//意図的に空にしたい場合はnullにする。undefinedは基本使わない

argumentsとは

function fn(a, b) {
  console.log(a, b);
}

fn(1, 2)

argumentsとは実引数のことである
上記のコードだと1と2が該当する

関数とオブジェクト

関数実行可能なオブジェクトである
実行可能な点以外は全て一緒

コールバック関数

他の関数の引数として渡された関数のこと

function hello(name) {
  console.log('hello' + name)
}

function fn(cd) {
  cb('Ren')
}

fn(hello)//結果: hello Ren
//実引数(上記だとhello)がコールバック関数

コールバック関数は無名関数を使って直接記述しても使用可能

function greet() {
  console.log('Hello')
}

setTimeout(greet, 2000)//2秒後にHelloと表示
//greetがコールバック関数

なぜコールバック関数が存在するのか?
上記のコードは「○秒後に実行」+「helloと表示」の2つの関数で成り立っている
関数helloを別なものに変更するだけで変更した関数も○秒後に発動できる
処理を切り分けることでコードの再利用性が高まっている

thisについて

thisは呼び出し元のオブジェクトへの参照を保持する
実行コンテキストによってthisの参照先は変わる

const person = {
  name: 'Ren',
  hello: function() {
    console.log('Hello' + this.name)
  }
}
person.hello() //結果 Hello Ren
//thisは呼び出し元のpersonを参照している

参照のコピーとthis

window.name = 'Miku'

const person = {
  name: 'Ren',
  hello: function() {
    console.log('Hello' + this.name)
  }
}
const ref = person.hello
ref(); //Hello Miku
//refにはhello()の参照先の関数が渡されるのでオブジェクトを経由しない。 
//thisはレキシカルスコープのwindowを参照する

以下のように考えることができる
オブジェクトのメソットとして実行される場合
'this' => 呼び出し元のオブジェクト

関数として実行される場合
'this' => グローバルオブジェクト

コールバック関数とthis

window.name = 'Miku'

const preson = {
  name: 'Ren',
  hello: function() {
    console.log('Hello', this.name)
  }
}

function fn(ref) {
  ref();
}

fn(person.hello)//Hello Miku
//refにはメソットの参照先の関数が直接入る(関数への直接の参照)
//オブジェクトは経由しないため、thisにはwindowオブジェクトが格納される
//レキシカルスコープはfnだが関数として実行されているためwindowオブジェクトを参照

メソットを他の変数に代入すると、オブジェクト経由で呼び出すのではなく関数を格納している変数から直接呼ぶため、呼び出し元のオブジェクトは基本的にwindowオブジェクトになる

bindとthis

bindを使うことでthisや引数を固定することができる
bindによるthisの束縛と呼ぶ
bindで固定する場合元の関数とは別の関数が新しく作成される

const preson = {
  name: 'Ren',
  hello: function() {
    console.log('Hello', this.name)
  }
}

const helloRen = person.hello.bind(person);
//person.helloのthisの参照を固定できる

function fn(ref) {
  ref();
}

fn(helloRen)//結果 Hello Ren;

---------------------------------------------------------
function a() {
  console.log('hello' + this.name);
}

const b = a.bind({name: 'Ren'});
b()//結果 hello Ren

引数を固定

function a(name) {
  console.log('Hello' + name);
}

const b = a.bind(null, 'Ren')
//第一引数はthis,第二引数は引数を固定する
//thisを必要としない場合nullにする

b()//結果: Hello Ren

applyとcall

bindとの違いは定義と同時に実行までされる点

function a(name, name1) {
  console.log('Hello ' + name + ' ' + name1);
}

const tim = {name: 'Tim'};

a.apply(tim, ['Ren', 'Miku']);//第一引数はthis,第二引数は(配列)を固定する
a.call(tim, 'Ren', 'Miku');//第一引数はthis,第二引数は引数を固定する
//applyとcallは定義するのと同時に実行まで行われる

アロー関数とは

無名関数を記述しやすくした省略記法

const b = (name) => {
  return 'hello' + name;
}

//引数が1つなら()は省略できる
//実行行が1行なら{}とreturnは省略できる

const b = name => 'hello' + name;

console.log(b('Ren'))//結果: hello Ren

無名関数とアロー関数の挙動には違いがある

- 無名関数 アロー関数
this x
arguments x
new x
prototype x

アロー関数とthis

アロー関数はthisを保持しないためレキシカルスコープに探しに行く
アロー関数はthiwを保持しないのでbind等で束縛もできない

const person = {
  name: 'Ren';
  hello: function() {
    console.log('Hello' + this.name)//Hello Ren
    //無名関数はthisを保持するためオブジェクトへの参照を保持
  }
}
window.name = 'Miku';
const person = {
  name: 'Ren';
  hello: () => {
    console.log('Hello' + this.name)// Hello Miku
    //アロー関数はthisを保持しないためレキシカルスコープ参照
    //このコードだとwindowオブジェクトがレキシカルスコープ
  }
}
window.name = 'Miku';
const person = {
  name: 'Ren';
  hello() {
    console.log('Hello' + this.name)// Hello Ren
    const a = ()  => console.log('Bye' + this.name)
    a();// Hello Ren
  }
}
//アロー関数はthisを保持しないためレキシカルスコープを参照
//このコードだと関数helloの関数スコープがレキシカルスコープ
//関数helloはメソットとして実行しているのでthisを保持している
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0