JavaScript拡張(3)関数、this指向、コピー
49130 ワード
JavaScriptプレミアム(3)
一、関数の定義と呼び出し
1、関数の定義方式関数の定義方法:1.関数宣言2.関数式3.Functionコンストラクタ を使用
2、関数呼び出し
二、this指向
1、関数内部thisの指向一般関数はwindow を指すオブジェクトの関数呼び出しは、呼び出し者 を指す.コンストラクタの呼び出しは、インスタンスオブジェクト を指す.バインディングイベントの処理関数はバインディング者 を指す.タイマの処理関数はwindow を指す.直ちに関数を実行してwindow を指します
2、callはthisの指向を変える fn.call([thisArg, arg1, arg2…]) の役割:関数を呼び出し、呼び出し時のthisの値 を指定します.パラメータ:thisArg関数のthisの指定値;arg 1,arg 2...オプションのパラメータリスト 戻り値:関数呼び出しの結果 注:最初のパラメータthisArgがnull、undefinedを渡さない場合、デフォルトの関数内thisはwindowを指します.
3、apply方法 fn.apply(thisArg,[ argsArray]) の役割:関数を呼び出し、呼び出し時のthisの値 を指定します.パラメータ:thisArg関数のthisの指定値;ArgsArrayオプションのパラメータ配列(!) 戻り値:関数呼び出しの結果 callメソッドとの違い: callメソッドは、2番目から各独立パラメータを伝達するが、applyはパラメータ配列 を伝達する. callが使用可能な場合、 の代わりにapplyを使用することができる.
4、bind方法 var newFn = fn.bind(thisArg,arg1, arg2, …) の役割:元の関数に基づいて新しい関数を作成します.この新しい関数のthisは最初のパラメータとして指定され、残りのパラメータは実パラメータとして新しい関数 に渡されます.パラメータ:thisArgは新しい関数内のthisのプリセット値です.arg 1,arg 2は、新しい関数プリセットの入力パラメータ である.戻り値:新しい関数(それ自体は関数を呼び出さない)
三、厳格モード
1、定義
制限されたJavaScriptバリエーションの1つを採用し,従来の緩和モードから脱した.
1. jsコードの不合理さと厳格さを解消し、奇妙な行為を減らす.
2. コードの不安全な場所を排除し、コードの安全な運行を保証する
3. コンパイラの効率化と実行速度の向上
4.ECMAScriptの将来のバージョンで定義される可能性のあるいくつかの構文class extends superなどを無効にします.使用:scripコードブロックの一番前に「use strict」を追加する.
2、厳格モードの変化変数宣言なしでは を直接付与できません.変数は、 を使用する前に宣言する必要があります.関数内のthisデフォルトはundefined を指します.非関数内のthisデフォルトはundefined を指します.構造関数とクラスはnewを加えてのみ を使用できます.関数のパラメータ名は、 に名前を変更できません.非関数のコードブロック内で関数を宣言することは許されない(chromeブラウザは実装されていない) 四、高次関数
他の関数を操作する関数には、主に2つのタイプの高次関数があります.
1. 関数をパラメータとする関数関数を戻り値とする関数 五、閉包
1、定義:
内部関数は外部関数が宣言する変数にアクセスします.この組み合わせは閉パッケージです.
2、JSにおけるゴミ回収メカニズム(GC)
ごみ回収メカニズムは、定期的に(周期的に)参照されなくなったメモリ(変数)を特定し、メモリを解放します.
3、閉包の原因
(1)1つの関数内の宣言された変数が他の関数に参照されていない場合、この関数を呼び出すと、すべての局所変数がゴミ回収メカニズムによって消去される.
(2)この変数が別の関数に参照されると,この変数の値は常にメモリに保存され,ゴミ回収機構によって回収されず,閉パケットとなる.
4、ケース:需要:各ボタンをクリックして現在のボタンのインデックス をポップアップするタクシーの価格を計算する タクシーの初乗り料金は8(3キロ以内)で、その後1キロごとに5元増加し、ユーザーはキロ数を入力すればタクシーの価格を出すことができ、渋滞があれば、前の価格に加えて10元の渋滞料金を徴収することができる.
通常のタクシー価格と混雑時のタクシー価格を求めるオブジェクトをパッケージ化し、全体的に初乗り価格と総価格にアクセスできません.
六、再帰関数関数の内部で自分で自分を呼び出し、作用と循環効果は に似ている.再帰は「スタックオーバーフロー」エラーが発生しやすいため、whileループと同様に割り込み条件 を追加する必要があります.
七、コピー
単純なデータ型はすべて直接コピーで、深浅コピーを区別しません
1、浅いコピー
オブジェクトの1レベルのデータのみをコピーし、複雑なデータ型はメモリアドレス値のみをコピーします(同じオブジェクトを参照).
2、深いコピーオブジェクトの多層データをコピーします.複雑なデータ型に遭遇すると、新しいスペースが作成され続け、各レイヤのプロパティと値 がコピーされます.と浅いコピーの違い 深いコピーされたオブジェクトと元のオブジェクトは完全に分離されており、それぞれは互いに影響しないが、浅いコピーのすべての複雑なデータ型の値は、共通参照の である.
3、補充浅いコピーで を迅速に実現深いコピーは を迅速に実現する. JSON.parse(JSON.stringify(obj)) JSON.stringify()は、複雑なデータ型を文字列 に変換することができる. JSON.parse()は文字列をオブジェクト に再変換することができる.
一、関数の定義と呼び出し
1、関数の定義方式
// 1.
function fn(a, b) {
return a + b;
};
// 2.
var fn1 = function() {
console.log('123');
};
// 3. Function
var fn2 = new Function('a', 'b', 'console.log(a+b)');
fn2(1, 2);
console.dir(fn2);
2、関数呼び出し
// 1.
function fn1() {
console.log(123);
}
fn1();
// 2.
var obj = {
say: function() {
console.log('hello');
}
};
obj.say();
// 3.
function Student(name, age) {
this.name = name;
this.age = age;
}
var xm = new Student(' ', 12);
console.log(xm);
// 4.
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log(' ');
});
// 5.
window.setTimeout(function() {
console.log('345');
}, 1000);
// 6.
var num = 10;
!(function() {
// ,
var num = 10;
console.log('hi');
})()
二、this指向
1、関数内部thisの指向
<div>hello</div>
<button> </button>
<script>
// 1.
function fn1() {
console.log(this); //window
}
fn1();
// 2.
var obj = {
say: function() {
console.log('hello');
}
};
obj.say(); //this obj
var foo = obj.say;
foo(); //this window
// 3.
var that;
function Student(name, age) {
that = this;
this.name = name;
this.age = age;
}
var xm = new Student(' ', 12);
console.log(xm);
console.log(xm === that);
// 4.
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log(' ');
console.log(this); // btn
});
// 5.
window.setTimeout(function() {
console.log(this); // window
}, 1000);
// 6.
var num = 10;
!(function() {
var num = 10;
console.log(this); // window
})()
2、callはthisの指向を変える
3、apply方法
function fn(a, b) {
console.log(this);
console.log(a, b);
}
fn.call({
}, 2, 3);
fn.apply({
}, [2, 3]);
// 1、 apply
var arr = [1, 254, 545, 12, 5];
var res = Math.max.apply(null, arr);
console.log(res);
4、bind方法
function fn(a, b) {
console.log(this);
console.log(a + b);
}
// bind ,
var newFn = fn.bind({
}, 3, 4);
newFn(); // this {}, ,bind
fn(3, 4) // this window
三、厳格モード
1、定義
制限されたJavaScriptバリエーションの1つを採用し,従来の緩和モードから脱した.
1. jsコードの不合理さと厳格さを解消し、奇妙な行為を減らす.
2. コードの不安全な場所を排除し、コードの安全な運行を保証する
3. コンパイラの効率化と実行速度の向上
4.ECMAScriptの将来のバージョンで定義される可能性のあるいくつかの構文class extends superなどを無効にします.
2、厳格モードの変化
他の関数を操作する関数には、主に2つのタイプの高次関数があります.
1. 関数をパラメータとする関数
1、定義:
内部関数は外部関数が宣言する変数にアクセスします.この組み合わせは閉パッケージです.
2、JSにおけるゴミ回収メカニズム(GC)
ごみ回収メカニズムは、定期的に(周期的に)参照されなくなったメモリ(変数)を特定し、メモリを解放します.
3、閉包の原因
(1)1つの関数内の宣言された変数が他の関数に参照されていない場合、この関数を呼び出すと、すべての局所変数がゴミ回収メカニズムによって消去される.
(2)この変数が別の関数に参照されると,この変数の値は常にメモリに保存され,ゴミ回収機構によって回収されず,閉パケットとなる.
4、ケース:
<button> </button>
<button> </button>
<button> </button>
<button> </button>
<button> </button>
<script>
// :
// :
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onclick = function() {
console.log(this.index);
}
}
//
for (var i = 0; i < btns.length; i++) {
// ,
(function(i) {
// : i ,
btns[i].onclick = function() {
console.log(i);
}
})(i)
}
通常のタクシー価格と混雑時のタクシー価格を求めるオブジェクトをパッケージ化し、全体的に初乗り価格と総価格にアクセスできません.
var obj = (function() {
var total = 0;
var start = 8;
return {
price: function(km) {
total = km <= 3 ? start : (km - 3) * 5 + start;
return total;
},
busyPrice: function(isBusy) {
total = isBusy ? total + 10 : total;
return total;
}
}
})()
console.log(obj.price(20));
console.log(obj.busyPrice(true));
六、再帰関数
// n m 5, 10 ===> 5 * 6 * ... * 10
function fn2(n, m) {
if (n == m) {
return m;
}
return n * fn2(n + 1, m);
}
var res2 = fn2(1, 5);
console.log(res2);
// ( ) 1, 1, 2, 3, 5, 8, 13, 21...
// n
function fn(n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fn(n - 1) + fn(n - 2);
// return n==0||n==1?n:fn(n - 1) + fn(n - 2);
}
console.log(fn(4));
//fn(3)+fn(2)==>fn(2)+fn(1)+fn(2)==>fn(1)+fn(0)+fn(1)+fn(2)==>fn(1)+fn(0)+fn(1)+fn(1)+fn(0)==>1+0+1+1+0=3
七、コピー
単純なデータ型はすべて直接コピーで、深浅コピーを区別しません
1、浅いコピー
オブジェクトの1レベルのデータのみをコピーし、複雑なデータ型はメモリアドレス値のみをコピーします(同じオブジェクトを参照).
var obj = {
id: 1,
name: ' ',
data: {
id: 2,
age: 19
}
}
var obj2 = {
};
// obj2 = obj;
//
for (var key in obj) {
// obj2
obj2[key] = obj[key]
}
obj.data.id = 10; // data id ,obj2 id
// data
console.log(obj2.data.id);
2、深いコピー
var obj1 = {
id: 1,
name: ' ',
data: {
id: 2,
age: 19,
goods: {
id: 10
}
},
arr: [1, 2, 3]
}
var obj2 = {
}
function deepClone(obj1, obj2) {
//
for (var key in obj1) {
var temp = obj1[key];
//
// ==> obj2 ,
if (Array.isArray(temp)) {
obj2[key] = [];
deepClone(temp, obj2[key]);
// ==> obj2 ,
} else if (temp instanceof Object) {
obj2 = {
};
deepClone(temp, obj2[key]);
// , obj2
} else {
obj2[key] = temp;
}
}
};
deepClone(obj1, obj2);
obj1.data.id = 10;
obj1.arr[0] = 100;
// obj2 obj1 ,
console.log(obj2.data.id);
console.log(obj2.arr[0]);
3、補充
var obj = {
a: 1,
b: 2,
c: {
d: 4
}
}
obj.c.d = 10;
var newObj = {
...obj
};
console.log(newObj);
var obj2 = JSON.parse(JSON.stringify(obj))
obj.c.d = 20;
console.log(obj2); //obj2