範囲と閉鎖
- トピック
- 知識のポイント
- 回答
トピック
さまざまなアプリケーションシナリオでこれの価値をどのように取るか?
分類:1:通常の関数として呼び出される場合、これが指すオブジェクトはウィンドウのポインターであり、これは一般に、誰が呼び出し、誰が指すかとして理解されます。
次に例を示します。
ここでのa()はwindow.a();と同等です。
function a(){
var user = "candy";
console.log(this,user); // undefined
console.log(this); // window
};
a();
次の例:
var o = {
user:"candy:,
fn:function(){
console.log(this.user); // candy
},
};
0.fn();
ここでのfnは0オブジェクトによって呼び出されるため、この時点でこれはオブジェクトoを指します。
例3:
var o = {
a:1,
b:{
a:2,
fn:function(){
console.log(this.a); // 2
}
}
};
o.b.fn();
この例では2が出力されます。つまり
、関数にこれがあり、呼び出しに複数のレイヤーが含まれている場合、これは前のレベルの呼び出し元オブジェクトのみを指します。
オブジェクトbには属性aはありませんが、これもオブジェクトbを指します。これは、このオブジェクトに必要なものがあるかどうかに関係なく、親オブジェクトのみを指すためです。
例4:より特別な
var o = {
a:1,
b:{
a:2,
function(){
console.log(this,a); // undefined
console.log(this); // window
}
}
};
var j = o.b.fn;
j();
ここでこれはウィンドウを指していますが、少し混乱していますか?実際、それはあなたが文章を理解していなかったからです。それもまた非常に重要です。
そのオブジェクトの呼び出しの最後に、このいつものポイントには、また、関数fnは、オブジェクトbが参照されるが、例4を起動し、誰が実行されたときに確認することですが、fnは、変数jに割り当てられたときに実行されなかった最後のポイントので、はwindowであり、fnを直接実行する例3とは異なります。
2:call、apply、bindを使用します。これが指すオブジェクトは着信オブジェクトです
。bind()メソッドは主に関数をオブジェクトに
バインドし、bind()は関数を作成し、このオブジェクトの値を作成します。関数本体では、bind()で渡された最初のパラメーターの値にバインドされます。
たとえば、fn.bind(obj)は、実際にはobj.fn()として理解できます。現時点では、これはfnです。関数本体は自然にobjを指します
function fn1(a,b,c){
console.log('this',this);
console.log(a,b,c);
return 'this is fn1';
}
const fn2 = fn1.bind({
x:100},10,20,30);
const res = fn2();
console.log(res);
印刷結果は次のとおりです
。3:オブジェクトとしてのメソッドが呼び出されると、呼び出されたオブジェクトが返されます。
4:クラスメソッド内
5:矢印関数で呼び出され、矢印関数の上位スコープを参照します
6:コンストラクターでこれ
function FU(){
this.user = "candy";
};
var a = new Fu();
console.log(a.user); // candy
これは、newキーワードが使用されているためです。newキーワード
は、コンストラクターのthisを指すオブジェクトインスタンスを作成するためのものです。
ただし
、コンストラクターと戻り
値が一致する場合は☝️の特殊なケースがあることに注意してください。戻り値がオブジェクトの場合、これは返されたオブジェクトを指し、戻り値がオブジェクトでない場合、これは次のインスタンスを指します。関数。
手書きバインド機能
MDNの標準ポリフィル
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {
},
fBound = function() {
// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fBound ? this : oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
}
実際の開発におけるクロージャのアプリケーションシナリオと例
クロージャの実際のアプリケーションは、主に変数をカプセル化するために使用されます。つまり、変数は取得および変更するために外部から隠されています。
function isFirstLoad() {
var _list = []
return function (id) {
if (_list.indexOf(id) >= 0) {
return false
} else {
_list.push(id)
return true
}
}
}
// 使用
var firstLoad = isFirstLoad()
firstLoad(10) // true
firstLoad(10) // false
firstLoad(20) // true
知識のポイント
- スコープと自由変数
- 閉鎖
- この
範囲
- グローバルスコープ
- 関数スコープ
- ブロックレベルのスコープ(ES6の新機能)
JavaScriptスコープ
スコープは、アクセス可能な変数のコレクションです。
JavaScriptスコープ
JavaScriptでは、オブジェクトと関数も変数です。
JavaScriptでは、スコープはアクセス可能な変数、オブジェクト、および関数のコレクションです。
JavaScript関数スコープ:スコープは関数内で変更されます。
JavaScriptローカルスコープ
変数は関数で宣言され、変数はローカルスコープです。
ローカル変数:関数内でのみアクセスできます。
例:
// 此处不能调用 carName 变量
function myFunction() {
var carName = "Volvo";
// 函数内可调用 carName 变量
}
ローカル変数は関数内でのみ機能するため、異なる関数で同じ名前の変数を使用できます。
ローカル変数は関数の実行開始時に作成され、ローカル変数は関数の実行後に自動的に破棄されます。
JavaScriptグローバル変数
関数の外部で定義された変数はグローバル変数です。
グローバル変数にはグローバルスコープがあります。Webページ内のすべてのスクリプトと関数を使用できます。
例:
var carName = " Volvo";
// 此处可调用 carName 变量
function myFunction() {
// 函数内可调用 carName 变量
}
変数が関数で宣言されていない場合(varキーワードは使用されていません)、変数はグローバル変数です。
次の例では、carNameは関数内にありますが、グローバル変数です。
例:
// 此处可调用 carName 变量
function myFunction() {
carName = "Volvo";
// 此处可调用 carName 变量
}
JavaScriptの可変ライフサイクル
JavaScript変数のライフサイクルは、宣言時に初期化されます。
関数の実行後、ローカル変数は破棄されます。
ページが閉じられると、グローバル変数は破棄されます。
関数パラメーター
関数パラメーターは関数内でのみ機能し、ローカル変数です。
HTMLのグローバル変数
HTMLでは、グローバル変数はウィンドウオブジェクトです。すべてのデータ変数はウィンドウオブジェクトに属します。
例:
//此处可使用 window.carName
function myFunction() {
carName = "Volvo";
}
自由変数
- 変数は現在のスコープでは定義されていませんが、使用されています
- 上位レベルのスコープに移動し、見つかるまで一度に1つのレイヤーを探します
- グローバルスコープが見つからない場合、エラーxxが定義されていませんが報告されます
閉鎖
- アプリケーションの特殊な状況には、2種類の症状があります
- 関数はパラメーターとして渡されます
- 関数は戻り
値として返されます関数は戻り値として返されます
function create(){
const a = 100
return function (){
console.log(a)
}
}
const fn = create()
const a = 200
fn() // 100
関数はパラメーターとして渡されます
function print (fn){
const a = 200
fn()
}
const a = 100
function fn(){
console.olg(a)
}
print(fn) // 100
したがって、自由変数の検索は関数が定義されている場所で行われ、実行の場所ではなく、上位のスコープで検索されます。!!!
この
- 通常の機能として
- call applybindを使用する
- オブジェクトメソッドとして呼び出されます
- クラスメソッドで呼び出されます
- 矢印関数で呼び出されます
実際の開発におけるクロージャの適用
- データを隠す
- たとえば
、クロージャ内のデータを非表示にする単純なキャッシュツールは、APIのみを提供します
function craeteCache(){
const data = {
} // 闭包中的数据,被隐藏,不被外界访问
return {
set:function (key,val){
data[key] = val
},
get:function (key){
return data[key]
}
}
}
const c = craeteCache()
c.set('a',100)
console.log(c.get('a'))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js 基础知识 演示</title>
</head>
<body>
<p>一段文字 1</p>
<p>一段文字 2</p>
<p>一段文字 3</p>
</body>
<script>
let a
// for(i=0; i<10;i++){
for(let i=0; i<10;i++){
a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click',function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
</script>
</html >
概要
- 作用と自由変数
- クロージャ:2つの一般的な方法と自由変数検索ルール
- この