s 6ノート--関数
5762 ワード
es 6参照:リンクを開くにはクリックしてください.
パラメータ
restパラメータの組み合わせの変数は、行列に余分なパラメータを入れた配列です.
関数パラメータが標準値、アンチエイジング、または拡張演算子を使用している限り、関数内部では明示的に厳格なモードに設定できません.そうでないとエラーが発生します.関数内部の厳密なモードは関数体と関数パラメータに適用されるからです.ただし、関数が実行される場合は、まず関数パラメータを実行してから関数体を実行します.このように不合理なところがあります.パラメータは厳密なモードで実行すべきかどうかは関数体の中からしか分かりませんが、パラメータは関数体より先に実行すべきです.
関数名を返します
矢印関数
(1)関数体内の
(2)コンストラクタとしてはいけません.つまり、使用してはいけません.
(3)使用できない
(4)使用できない
二重コロン演算
矢印関数は、バインディング
1、テールコール
関数プログラミングの重要な概念は、関数の最後のステップを指します.関数の呼び出しです.
関数aで関数bを呼び出すと、aの呼出フレーム上でbの呼出フレームが開かれ、メモリを占めます(bでcが呼び出されたら、呼び出されたスタックが階層的に形成されます).テイルコールの関数が外層関数に依存しない場合は、aの呼び出しフレームを削除し、bの呼び出しフレームを保持することで、メモリを大幅に節約することができます.
2、ES 6の終端呼び出し最適化は厳格なモードでのみ開かれ、正常モードは無効です.これは、通常モードでは関数内部に2つの変数があります. トレース関数でコールスタックを呼び出します.
最後の呼び出し最適化が発生すると、関数の呼び出しスタックが書き換えられますので、上の二つの変数が歪みます.厳密モードではこの2つの変数を無効にしますので、最後の呼び出しモードは 厳格なモードで有効です.
最後に再帰する
名前の通り、関数の最後に呼び出されました.呼出されたのは自分で再帰的に形成されたものです.今回は絶えずコールフレームが生まれ、コールスタックが形成されています.最大コールスタックを超える可能性があります.だから、最適化を考えています.再帰的を循環に変えます.
次は再帰的なものです.私達は酔っ払いコールスタックを超えて運行します.
上のコードで、
パラメータ
restパラメータの組み合わせの変数は、行列に余分なパラメータを入れた配列です.
function sorNumber(){
return [].slice.call(arguments,0).sort()
}
function sorNumberRest(x,y,...values){
return values.sort()
}
sorNumber(1,8,9,6,7,8,4,3,2); //[2, 3, 4, 6, 7, 8, 9]
sorNumberRest(1,8,9,6,7,8,4,3,2); //1, 2, 3, 4, 6, 7, 8, 8, 9
関数の厳密なモード: 関数パラメータが標準値、アンチエイジング、または拡張演算子を使用している限り、関数内部では明示的に厳格なモードに設定できません.そうでないとエラーが発生します.関数内部の厳密なモードは関数体と関数パラメータに適用されるからです.ただし、関数が実行される場合は、まず関数パラメータを実行してから関数体を実行します.このように不合理なところがあります.パラメータは厳密なモードで実行すべきかどうかは関数体の中からしか分かりませんが、パラメータは関数体より先に実行すべきです.
function a(value = 070){"use strict"}
name属性関数名を返します
矢印関数
let foo = () => 5;// 5
let foo = (x,y,...values) => { return {x+y,values} };// , return
注意: (1)関数体内の
this
オブジェクトは、使用時の対象ではなく定義時の対象です.(2)コンストラクタとしてはいけません.つまり、使用してはいけません.
new
コマンドでないと、エラーが発生します.(3)使用できない
arguments
オブジェクトは、関数内に存在しません.使うなら、restパラメータで代替できます.(4)使用できない
yield
コマンドですので、矢印関数はGenerator関数として使用できません. 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
矢印関数のこの特性をどのように実現しましたか?function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
ここでは、矢印関数は直接呼び出された外層のthisであり、同じことからわかるthis
、arguments
・、super
・new.target
矢印関数の中にも存在せず、外層関数に対する対応変数を指す.二重コロン演算
矢印関数は、バインディング
this
オブジェクトとして、明示的バインディングthis
オブジェクトの書き方を大幅に低減しています(call
・apply
・bind
).しかし、矢印関数はすべての場合には適用されないので、現在は「関数バインディング」演算子を提案しています.foo::bar;
//
bar.bind(foo);
foo::bar(...arguments);
//
bar.apply(foo, arguments);
const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return obj::hasOwnProperty(key);
}
// , ,
var method = obj::obj.foo;
//
var method = ::obj.foo;
let log = ::console.log;
//
var log = console.log.bind(console);
// , , 。
import { map, takeWhile, forEach } from "iterlib";
getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));
テールコール最適化1、テールコール
関数プログラミングの重要な概念は、関数の最後のステップを指します.関数の呼び出しです.
function f(x){
return g(x);
}
/*************************** *****************************/
//
function f(x){
let y = g(x);
return y;
}
//
function f(x){
return g(x) + 1;
}
//
function f(x){
g(x);
}
2、テールコールの最適化:関数aで関数bを呼び出すと、aの呼出フレーム上でbの呼出フレームが開かれ、メモリを占めます(bでcが呼び出されたら、呼び出されたスタックが階層的に形成されます).テイルコールの関数が外層関数に依存しない場合は、aの呼び出しフレームを削除し、bの呼び出しフレームを保持することで、メモリを大幅に節約することができます.
function a(param){
var v1 = 1,
v2 = 2;
return b(param);
}
function a(param){
var v1 = 1;
function inner(b){
return b + v1;
}
return inner(param);
}
注意:1、ここのパラムはその値をパラメータとしてbに渡すだけです.パラムの値は変数パラムではなく、パラム変数に依存していません.2、ES 6の終端呼び出し最適化は厳格なモードでのみ開かれ、正常モードは無効です.これは、通常モードでは関数内部に2つの変数があります. トレース関数でコールスタックを呼び出します.
call
:呼び出し時関数のパラメータを返します.apply
bind
:現在の関数を呼び出した関数を返します.最後の呼び出し最適化が発生すると、関数の呼び出しスタックが書き換えられますので、上の二つの変数が歪みます.厳密モードではこの2つの変数を無効にしますので、最後の呼び出しモードは 厳格なモードで有効です.
最後に再帰する
名前の通り、関数の最後に呼び出されました.呼出されたのは自分で再帰的に形成されたものです.今回は絶えずコールフレームが生まれ、コールスタックが形成されています.最大コールスタックを超える可能性があります.だから、最適化を考えています.再帰的を循環に変えます.
次は再帰的なものです.私達は酔っ払いコールスタックを超えて運行します.
function sum(x, y) {
if (y > 0) {
return sum(x + 1, y - 1);
} else {
return x;
}
}
sum(1, 100000)
トランポリン関数(trmpoline)は再帰的な実行を循環的に実行することができます.function trampoline(f) {
while (f && f instanceof Function) {
f = f(); // , ,
}
return f;
}
function sum(x, y) {
if (y > 0) {
return sum.bind(null, x + 1, y - 1);
} else {
return x;
}
}
trampoline(sum(1, 100000))
// 100001
トランポリンの機能は本当の最後の再帰的最適化ではなく、次の実現こそです.function tco(f) {
var value;
var active = false;
var accumulated = [];
return function accumulator() {
accumulated.push(arguments);
if (!active) {
active = true;
while (accumulated.length) {
value = f.apply(this, accumulated.shift());
}
active = false;
return value;
}
};
}
var sum = tco(function(x, y) {
if (y > 0) {
return sum(x + 1, y - 1)
}
else {
return x
}
});
sum(1, 100000)
// 100001
上のコードで、
func.arguments
関数は最後の再帰的最適化の実現であり、その奥妙は状態変数にあります.
.デフォルトでは、この変数は非アクティブです.最後の再帰的最適化のプロセスに入ると、この変数はアクティブになります.そして、その都度再帰する. func.caller
帰るのは全部tco
したがって、再帰的な実行は避けられます.に対するactive
配列保存sum
実行するパラメータは、常に値があることを保証します.undefined
関数内部のaccumulated
ループは常に実行されます.このように「再帰」を巧みに「循環」に変え、その後、一輪のパラメータが前回のパラメータに取って代わります.