Adakah fungsi es6 anak panah berfungsi pengaturcaraan?

青灯夜游
Lepaskan: 2023-01-11 17:15:40
asal
1517 orang telah melayarinya

Ya. Fungsi anak panah ialah manifestasi pengaturcaraan fungsian lebih memfokuskan pada hubungan antara input dan output, mengetepikan beberapa faktor dalam proses itu, fungsi anak panah tidak mempunyai ini, hujah, dan sasaran baharu ( ES6) dan super (ES6) fungsi anak panah adalah bersamaan dengan fungsi tanpa nama, jadi baru tidak boleh digunakan sebagai pembina.

Adakah fungsi es6 anak panah berfungsi pengaturcaraan?

Persekitaran pengendalian tutorial ini: sistem Windows 7, ECMAScript versi 6, komputer Dell G3.

Fungsi anak panah

Fungsi anak panah ialah ciri baharu yang diperkenalkan dalam ES6, yang menggunakan "anak panah" (=>) untuk mentakrifkan fungsi.

var f = v => v;
// 等同于
var f = function (v) {
  return v;
};
Salin selepas log masuk

Jika fungsi anak panah tidak memerlukan parameter atau memerlukan berbilang parameter, gunakan tanda kurung untuk mewakili bahagian parameter.

var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};
Salin selepas log masuk

Jika blok kod fungsi anak panah adalah lebih daripada satu pernyataan, gunakan kurungan kerinting untuk melampirkannya dan gunakan pernyataan kembali untuk kembali.

var sum = (num1, num2) => { return num1 + num2; }
Salin selepas log masuk

Memandangkan kurungan kerinting ditafsirkan sebagai blok kod, jika fungsi anak panah mengembalikan objek secara langsung, anda mesti menambah kurungan di luar objek, jika tidak, ralat akan dilaporkan.

// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });
Salin selepas log masuk

Berikut adalah kes khas, walaupun ia boleh dijalankan, ia akan mendapat hasil yang salah.

let foo = () => { a: 1 };
foo() // undefined
Salin selepas log masuk

Dalam kod di atas, niat asal adalah untuk mengembalikan objek { a: 1 }, tetapi kerana enjin berpendapat bahawa pendakap kerinting adalah blok kod, ia melaksanakan baris pernyataan a: 1 . Pada masa ini, a boleh ditafsirkan sebagai label pernyataan, jadi pernyataan yang sebenarnya dilaksanakan ialah 1;, dan kemudian fungsi itu berakhir tanpa nilai pulangan.

Jika fungsi anak panah hanya mempunyai satu baris pernyataan dan tidak perlu mengembalikan nilai, anda boleh menggunakan kaedah penulisan berikut tanpa menulis kurungan kerinting.

let fn = () => void doesNotReturn();
Salin selepas log masuk

Penjelasan:

Fungsi anak panah ialah manifestasi pengaturcaraan fungsian lebih memfokuskan pada input dan Perhubungan output menghapuskan beberapa faktor proses, jadi fungsi anak panah tidak mempunyai ini sendiri, argumen, sasaran baharu (ES6) dan super (ES6). Fungsi anak panah adalah bersamaan dengan fungsi tanpa nama, jadi baharu tidak boleh digunakan sebagai pembina.

Ini dalam fungsi anak panah sentiasa menunjuk ke ini dalam skop induknya. Dalam erti kata lain, fungsi anak panah menangkap nilai konteks ini di mana ia terletak sebagai nilai ini sendiri. Penunjuknya tidak boleh ditukar dengan sebarang kaedah, seperti call(), bind(), apply(). Apabila memanggil ini dalam fungsi anak panah, ia hanya mencari rantai skop untuk mencari ini yang terdekat dan menggunakannya Ia tiada kaitan dengan konteks panggilan. Mari jelaskan menggunakan kod.

Fungsi anak panah boleh digunakan bersama dengan pemusnahan pembolehubah

const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
  return person.first + ' ' + person.last;
}
Salin selepas log masuk

Fungsi anak panah menjadikan ungkapan lebih ringkas

const isEven = n => n % 2 === 0;
const square = n => n * n;
Salin selepas log masuk

Kod di atas hanya menggunakan dua baris untuk mentakrifkan dua fungsi alat mudah. Jika fungsi anak panah tidak digunakan, ia mungkin mengambil beberapa baris, dan ia tidak akan menarik perhatian seperti sekarang.

Satu penggunaan fungsi anak panah adalah untuk memudahkan fungsi panggil balik

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);
Salin selepas log masuk

Contoh lain ialah

// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});
// 箭头函数写法
var result = values.sort((a, b) => a - b);
Salin selepas log masuk

Berikut ialah parameter selebihnya dan fungsi anak panah Menggabungkan contoh.

const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]
Salin selepas log masuk

Langkah berjaga-jaga penggunaan

Terdapat beberapa langkah berjaga-jaga penggunaan untuk fungsi anak panah.

(1) Objek ini dalam badan fungsi ialah objek di mana ia ditakrifkan, bukan objek di mana ia digunakan.

(2) tidak boleh digunakan sebagai pembina, iaitu arahan baru tidak boleh digunakan, jika tidak ralat akan dilemparkan.

(3) Objek argumen tidak boleh digunakan, kerana objek itu tidak wujud dalam badan fungsi. Jika anda ingin menggunakannya, anda boleh menggunakan parameter selebihnya.

(4) Perintah hasil tidak boleh digunakan, jadi fungsi anak panah tidak boleh digunakan sebagai fungsi Penjana.

Di antara empat perkara di atas, perkara pertama amat perlu diberi perhatian. Penunjuk objek ini berubah-ubah, tetapi dalam fungsi anak panah, ia tetap.

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
Salin selepas log masuk

Dalam kod di atas, parameter setTimeout ialah fungsi anak panah takrifan fungsi anak panah ini berkuat kuasa apabila fungsi foo dijana dan pelaksanaan sebenar tidak akan menunggu sehingga 100 milisaat kemudian. Jika ia adalah fungsi biasa, ini harus menunjuk ke tetingkap objek global apabila dilaksanakan, dan 21 harus dikeluarkan pada masa ini. Walau bagaimanapun, fungsi anak panah menyebabkan ini sentiasa menunjuk ke objek di mana definisi fungsi berkuat kuasa (dalam kes ini, {id: 42}), jadi output ialah 42.

Fungsi anak panah membenarkan ini dalam setTimeout untuk terikat pada skop di mana ia ditakrifkan, dan bukannya menunjuk ke skop di mana ia dijalankan. Ini satu lagi contoh.

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
Salin selepas log masuk

Dalam kod di atas, dua pemasa disediakan di dalam fungsi Pemasa, masing-masing menggunakan fungsi anak panah dan fungsi biasa. Yang ini dari yang pertama terikat pada skop di mana ia ditakrifkan (iaitu, fungsi Pemasa), dan yang ini yang terakhir menunjukkan kepada skop di mana masa jalan adalah (iaitu, objek global). Jadi, selepas 3100 milisaat, timer.s1 telah dikemas kini sebanyak tiga kali, tetapi timer.s2 tidak dikemas kini sekali.

Fungsi anak panah boleh membetulkan perkara ini, yang sangat membantu untuk merangkum fungsi panggil balik. Di bawah ialah contoh di mana fungsi panggil balik acara DOM dirangkumkan dalam objek.

var handler = {
  id: '123456',
  init: function() {
    document.addEventListener('click',
      event => this.doSomething(event.type), false);
  },
  doSomething: function(type) {
    console.log('Handling ' + type  + ' for ' + this.id);
  }
};
Salin selepas log masuk

Dalam kaedah init kod di atas, fungsi anak panah digunakan, yang menyebabkan ini dalam fungsi anak panah sentiasa menghala ke objek pengendali. Jika tidak, apabila fungsi panggil balik berjalan, baris this.doSomething akan melaporkan ralat, kerana ini menunjuk ke objek dokumen pada masa ini.

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

所以,箭头函数转成 ES5 的代码如下。

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}
// ES5
function foo() {
  var _this = this;
  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}
Salin selepas log masuk

上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的this,而是引用外层的this。

请问下面的代码之中有几个this?

function foo() {
  return () => {
    return () => {
      return () => {
        console.log('id:', this.id);
      };
    };
  };
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
Salin selepas log masuk

上面代码之中,只有一个this,就是函数foo的this,所以t1、t2、t3都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this,它们的this其实都是最外层foo函数的this。

除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments、super、new.target。

function foo() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
Salin selepas log masuk

上面代码中,箭头函数内部的变量arguments,其实是函数foo的arguments变量。

另外,由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

(function() {
  return [
    (() => this.x).bind({ x: 'inner' })()
  ];
}).call({ x: 'outer' });
// ['outer']
Salin selepas log masuk

上面代码中,箭头函数没有自己的this,所以bind方法无效,内部的this指向外部的this。

长期以来,JavaScript 语言的this对象一直是一个令人头痛的问题,在对象方法中使用this,必须非常小心。箭头函数”绑定”this,很大程度上解决了这个困扰。

【相关推荐:javascript视频教程编程视频

Atas ialah kandungan terperinci Adakah fungsi es6 anak panah berfungsi pengaturcaraan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan