これは以下を指します: 1. 通常の関数またはオブジェクト属性として、ウィンドウ オブジェクトを指します; 2. イベント バインディング内で、バインドされたイベントの要素を指します; 3. コンストラクター内で、クラスのインスタンス; 4. 矢印 関数では、最も近い親コンテキストで this を指します; 5. call/apply/bind では、渡された最初のパラメーターを指します。
このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター
JavaScript
中this
次の状況を指します:
call/apply/bind
Specify一つずつ紹介しましょう
this
は、メソッドの実行前に「ドット」があるかどうかによって決まります。「ドット」がある場合は、その「ドット」の前にいる人が決まります。 this になります。ドットがない場合、
this は
window
const fn = function () { console.log(this); }; const obj = { name: 'OBJ', fn }; fn(); obj.fn(); const fn1 = obj.fn; fn1();
1. window 2. {name: 'OBJ', fn: function() {console.log(this)}} // obj 3. window
this は関数を呼び出したオブジェクトを指します。それ以外の場合、その
this は
window を指します。
this はバインディング イベントの要素です:
// 假设页面中有id为button的button元素 // var x = 100; window.x = 100; const fn = function () { console.log(this.x); }; const obj = { x: 200, fn }; const $button = document.getElementById('button'); $button.x = 300; obj.fn(); const fn1 = obj.fn; fn1(); $button.addEventListener('click', fn); $button.addEventListener('mouseenter', obj.fn); $button.addEventListener('mouseleave', function () {obj.fn();});
1. 200 2. 100 3. 点击button时:300 4. 鼠标移入button时:300 5. 鼠标移出时:200
this を
DOM# にポイントするのに役立ちます。 ## イベントにバインドされた要素。対応するイベントがコードを通じてトリガーされる場合は、call/apply/bind
( new Fn#) を通じてその
this
$button.click.call() // this为window,打印结果为100
コンストラクター (new Fnthis は、現在のクラス (
です) のインスタンスです。 new キーワードは、これを行うのに役立ちます:
var x = 100; const Fn = function () { this.x = 200; console.log(this.x); }; const fn = new Fn();
answer:
1. 200
arrow function
は、最も近い親コンテキスト の
this
const fn = function () { console.log(this); setTimeout(() => { console.log(this); }, 1000); setTimeout(function () { console.log(this); }); }; const obj = { x: 100, fn }; obj.fn();
answer:
1. {x:100, fn: function() {...}} // obj 2. window 3. {x:100, fn: function() {...}} // obj
に渡される最初のパラメータとして
を指すようにします。関数の thisvar x = 100; const obj = { x: 200, y: 200 }; const fn = function () { console.log(this.x); }; fn(); fn.call(obj); fn.apply(obj); const fixedThisFn = fn.bind(obj); fixedThisFn();
answer:
1. 100 2. 200 3. 200 4. 200
call実行時の最初のパラメータは
this 実行時のパラメータ
apply 実行時、最初のパラメータは
this 実行時のパラメータで構成される配列です。配列内の各項目は、
fn
bind ## の各パラメータに対応します。 #実行時、最初のパラメータは事前に this
に渡されたポインタ、以降のパラメータは実際に fixedThisFn
、fixedThisFn
は内部で fn
を呼び出し、その this
が
を指すように指定します。より深い理解
call/apply/bind は、関数内で
this call/apply/bind
ソース コードの実装
は関数を呼び出すオブジェクト
const obj = { x: 100, fn () {console.log(this);} }; obj.fn(); // {x: 100, fn: function() {...}} => obj
のこの機能を使用すると、実行された関数を call/ の最初のパラメーター
context
を実行し、context
を渡します。この属性に対応する関数を呼び出すには、関数の this
が context
## を指します。
#call ソース コードのシミュレーションは次のとおりです。
Function.prototype.myOwnCall = function (context, ...args) { const uniqueKey = new Date().getTime(); // this为调用call方法的函数 context[uniqueKey] = this; // 作为对象的方法被对象调用,this指向该对象context const result = context[uniqueKey](...args); delete context[uniqueKey]; return result; };
この時点で、
context が call/ に渡されたらどうなるかに気付いた友人もいるかもしれません。 apply はオブジェクトではありませんか?
mdn による
call メソッドの最初のパラメーターの説明を見てみましょう:
function.call( thisArg 、 arg1、 arg2、 ...) *
thisArg
functionメソッドでこの関数を呼び出します。関数の実行時に使用される
this
値。this
は、このメソッドで表示される実際の値ではない可能性があることに注意してください。この関数が非厳密モードの場合、
の場合は、null
またはunknown
になります。指定すると、グローバル オブジェクトを指すように自動的に置き換えられ、元の値がラップされます。次に、
myOwnCallメソッドの最初のパラメーターを次のように処理します。
は、function translateToObject (context) { // 可以通过 == 进行判断 context == null // null == undefined => 2个等号是成立的 // null,undefined => window if (typeof context === 'undefined' || context === null) { context = window; } else if (typeof context === 'number') { // 原始值转换为包装对象 context = new Number(context); } else if (typeof context === 'string') { context = new String(context); } else if (typeof context === 'boolean') { context = new Boolean(context); } return context; }ログイン後にコピー
myOwnCall
Function.prototype.myOwnCall = function (context, ...args) { context = translateToObject(context); const uniqueKey = new Date().getTime(); // this为调用call方法的函数 context[uniqueKey] = this; // 作为对象的方法被对象调用,this指向该对象context const result = context[uniqueKey](...args); delete context[uniqueKey]; return result; };
apply の実装は、基本的に call# と同じです。 ## (2 番目を除く) パラメーターは配列です: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">Function.prototype.myOwnBind = function (context, paramsArray) {
context = translateToObject(context);
const uniqueKey = new Date().getTime();
// this为调用call方法的函数
context[uniqueKey] = this;
// 作为对象的方法被对象调用,this指向该对象context
const result = context[uniqueKey](...paramsArray);
delete context[uniqueKey];
return result;
};</pre><div class="contentsignin">ログイン後にコピー</div></div><p>相比于<code>call/apply
,bind
函数并没有立即执行函数,而是预先传入函数执行时的this
和参数,并且返回一个函数,在返回的函数中执行调用bind
函数并将预先传入的this
和参数传入
bind
的源码模拟:
Function.prototype.myOwnBind = function (context, ...outerArgs) { const fn = this; return function (...innerArgs) { return fn.call(context, ...outerArgs, ...innerArgs); }; };
精简版如下:
Function.prototype.myOwnBind = (context, ...outerArgs) => (...innerArgs) => this.call(context, ...outerArgs, ...innerArgs);
这里并没有实现通过new
操作符来执行fn.bind(context)
的操作,如果想知道其详细的实现过程,可以看我的这篇文章: JS进阶-手写bind
在深入理解call/apply/bind
的实现原理后,我们尝试完成下面的测试:
function fn1 () {console.log(1);} function fn2 () {console.log(2);} fn1.call(fn2); fn1.call.call(fn2); Function.prototype.call(fn1); Function.prototype.call.call(fn1);
answer:
1. 1 2. 2 3. 什么都不输出 4. 1
这里我们根据call
的源码来进行推导一下Function.prototype.call.call(fn1)
,其它的执行过程类似:
// 1. 首先会将Function.prototype.call作为一个函数来执行它原型上的call方法 // 所以call方法内部: // this => Function.prototype.call // context => fn1 // 通过对象的属性来执行方法改变this指向 // fn1[uniqueKey] = this(Function.prototype.call) // fn1[uniqueKey]() // 执行 Function.prototype.call方法,但是this是context // 2. 在this为fn1的情况下执行Function.prototype.call方法 // 所以call方法内部: // this => fn1 // context => window // 通过对象的属性来改变this指向 // window[uniqueKey] = fn1 // window[uniqueKey]() // 执行fn1(),但是this是window
更多编程相关知识,请访问:编程入门!!
以上がJavaScript はどこを指しているのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。