javascript callの使用

9777 ワード


Javascriptではcallの使用は自分の感覚で葛藤しています.文書によってよく分かりますが、本当に理解しているかどうかを確認するのは難しいです.
コール方法は、Functionオブジェクトがオブジェクトを呼び出す方法で、現在のオブジェクトを別のオブジェクトに置き換えます.call([thisObj],arg 1[,arg 2[,   [.argN]]]パラメータ:thisObj オプションを選択します.現在のオブジェクトとして使用されます. arg 1,arg 2,argN オプションを選択します.転送される方法のパラメータ系列を指定します. 説明:コール方法は、他のオブジェクトの代わりに一つの方法を呼び出すために使用されてもよい.call方法は、関数のオブジェクトコンテキストを初期のコンテキストから、thisObjによって指定された新しいオブジェクトに変更することができる.thisObjパラメータが提供されていない場合、GlobalオブジェクトはthisObjとして使用される.
1.基本的な理解:例1
クラスをカスタマイズして、クラスには現在のオブジェクトのname値を表示する方法があります.
オブジェクトを作成し、オブジェクトのname値はtest 1に等しい.
call方法を使って、新たに作成したオブジェクトobjにクラス1のshowTxtを追加する方法、つまりクラス1のthis.showTxtの中のthisをobjに指定すると、objにshowTxt方法があります.「test 1」をイジェクトします
 
function Class1() {
    this.showTxt = function() {
        alert(this.name)
    }
}
var obj = new Object();
obj.name = "test1"Class1.call(obj);
obj.showTxt(); //test1alert(obj.showTxt);//function(){alert(this.name)}
 
この例は分かりやすい.
2.もう少し深く理解してください.
例2:Class 1を作成する場合、このインスタンスにshowTxt方法を呼び出して、このインスタンスのname値を返させます.これはname値がないため、undefineに戻ります.
function Class1() {
    this.showTxt = function() {
        alert(this.name)
    }
}
var class1 = new Class1();
class1.showTxt(); //undefinedalert(class1.showTxt);//function(){alert(this.name)}
 
例3:次にクラス1にname値を追加します.ここでクラス1がshowTxtメソッドを呼び出して、クラス1に戻ります.これはクラスにname値を追加したため、インスタンスのnameもundefineからクラス1になりました.
function Class1() {
    this.name = 'class1'; //  name     this.showTxt = function(){alert(this.name)}}var class1 = new Class1();class1.showTxt();//class1alert(class1.showTxt);//function(){alert(this.name)}
    
 
例4:Class 1.cal(obj)この操作は、クラス1のthis.name、this.showTxtのthisをobjに置き換えたので、obj.name='class 1'になったので、Obj.showTxtは実行時にclass 1に戻ります.
function Class1() {
    this.name = 'class1'; //  name     this.showTxt = function(){alert(this.name)}}function Class2(){    this.name = 'class2';}var class2 = new Class2();Class1.call(class2);alert(class2.showTxt);//function(){alert(this.name)}class2.showTxt();//class1
    
 例5:Class 1.calであれば(obj);その後、obj.name='test 1'を追加し、最終結果はtest 1を入力します.原因は明らかです.
function Class1() {
	this.name = 'class1'; //  name     this.showTxt = function(){alert(this.name)}
}
function Class2() {
	this.name = 'class2';
}
var class2 = new Class2();
Class1.call(class2);
class2.name = 'test1'; //   obj.name alert(class2.showTxt);//function(){alert(this.name)}class2.showTxt();//test1
 
上記の例はいずれもオブジェクトの一例です.次のケースはオブジェクトのインスタンスを直接関数に変えて、実行結果にどのような変化があるかを確認してください.
3.callメソッドの第一パラメータを実例から関数に変えてみたらどうなりますか?
例6:Class 2は、functionオブジェクトの参照であり、Class 1.cal(Class 2)を実行する際に、this.showTxtのthisをクラス2に置き換えた.このようにClass 2にはshowTxt方法があります.Class 2.showTxt()は実行時にクラス2.nameの値を返します.Class 2はname値を定義していないので、undefinedに戻ります.
Class 2関数の中のthis.nameはクラス2によってインスタンスを作成するname値で、クラス2.nameではなく、この二つの値は時々私を混乱させます.
function Class1() {
	this.showTxt = function() {
		alert(this.name)
	}
}
function Class2() {
	this.name = 'class2';
}
Class1.call(Class2);
alert(Class2.showTxt); //function(){alert(this.name)}Class2.showTxt();//undefined
 
4.次の例を見ます.
例7:class 1.showTxt.class 2;class 2に戻ったのは、function(){alert}ここのthisがcallでclass 2に指定され、alert(clast 2.name)になったから、クラス2に戻ります.
alert(clast.showTxt)はundefinedに戻り、class.showTxtを定義していない方法を説明します.
function Class1() {
	this.showTxt = function() {
		alert(this.name)
	}
}
function Class2() {
	this.name = 'class2';
}
var class1 = new Class1();
var class2 = new Class2();
class1.showTxt.call(class2); //class2alert(class2.showTxt);//undefined
 
class 2にshowTxt方法を追加するために、このエラーを提示します.この呼び出しの前にクラス1.calを追加したら(クラス2).この呼び出しでOKです.
Class1.call(class2);
class2.showTxt();//class1
 
例8:この例はundefinedに戻ります.
function Class1() {
	this.showTxt = function() {
		alert(this.name)
	}
}
function Class2() {
	this.name = 'class2';
}
var class1 = new Class1();
class1.showTxt.call(Class2); //undefinedalert(Class2.showTxt);//undefined
 
5.コールを使う時、コール機能にthisがないとどうなりますか?
例9:
function add(a, b) {
	alert(a + b);
}
function sub(a, b) {
	alert(a - b);
}
add.call(sub, 3, 1); //4
 
その結果、4を返します.add.call(sub,3,1)は実行中、subはadd関数の中でthisの代替品として現れましたが、addにはthisが使用されていませんので、sub関数は直接無視されました.
したがって、実際には次のように実行されます.4を返します.
function add(a, b) {
	alert(a + b);
}
add(3, 1); //4
 
6.いいです.次は変な形を理解します.
例10:
function f1() {
	alert(1);
}
function f2() {
	alert(2)
}
var f3 = f1.call;
f1.call(f2); //1f3.call(f2);//2
 
f 1.call(f 2)分かりやすいです.上のcaseを見て理解しないと、f 3 cal(f 2)は2に戻りますか?分かりやすいように等価変化をしてf 1.cal.call(f 2)にします.実際にf 1.calメソッドでf 2を呼び出したということが分かりますが、f 1はどうしてコール方法がありますか?call,appyはいずれもFunction.プロトタイプの一つの方法であり,JavaScriptエンジン内に実装されている.Function.prototypeに属しているので,Functionオブジェクトの各インスタンス,すなわち各方法にcall,apply属性がある.
f 1.cal.call(f 2)を理解するには、まずcall方法がどのように実行されているかを知りたいです.そうすると、f 1.cal.call(f 2)はどのように実行されますか?
例11:
JK。を参照して書いたappyでcallを実現する方法:
function jsCall(oThis) { //   jsCall  Call   
	var argsNew = [];
	for (var i = 1; i < arguments.length; i++) {
		argsNew.push(arguments[i]);
	}
	return this.apply(oThis, argsNew);
}
Function.prototype.jsCall =
 
または簡単に作成します
function jsCall(oThis) { //   jsCall  Call  
	var argsNew = [].slice.call(arguments, 1) return this.apply(oThis, argsNew);
}
Function.prototype.jsCall = jsCall;
jsCall;
 
これで、callと同じ機能のjsCallが得られました.
次に、2つの関数f 1,f 2を構築する.
function f1(a) {
	alert([this, a, 'f1']);
}
f1(11); //[object Window],11,f1
function f2(a) {
	alert([this, a, 'f2']);
}
f2(22); //[object Window],11,f2
 
jsCallでf 1の中のthisをf 2に置換します.
function f1(a) {
	alert([this, a, 'f1']);
}
function f2(a) {
	alert([this, a, 'f2']);
}
f1.jsCall(f2, 11); //function f2(a){alert([this, a, "f2"]);},11,f1
 
実行結果、「object Window」がf 2関数に置き換えられていることが分かりました.
function jsCall(oThis) { //   jsCall  Call   
	var argsNew = [].slice.call(arguments, 1) return this.apply(oThis, argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a) {
	alert([this, a, 'f1']);
}
function f2(a) {
	alert([this, a, 'f2']);
}
f1.jsCall.jsCall(f2, 11); //11,,f2
 
実行中f 1.jsCall.jsCall(f 2,11);は11、f 2を返します.なぜこの結果に戻りましたか?ポイントが来ました.)
f 1.jsCall方法:
alert(f1.jsCall);
//  
//function jsCall(oThis) {
//    var argsNew = [].slice.call(arguments, 1);
//    return this.apply(oThis, argsNew);
//}
 
だからf 1.jsCall.jsCallをjsCallに置き換えて実行結果を見てください.
function jsCall(oThis) { //   jsCall  Call 
	var argsNew = [].slice.call(arguments, 1) return this.apply(oThis, argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a) {
	alert([this, a, 'f1']);
}
function f2(a) {
	alert([this, a, 'f2']);
}
jsCall.jsCall(f2, 11); //11,,f2
 
分析を続ける
jsCallは実行する過程の中で、return this.apply(oThis、args New);のthisをf 2に変えました.11はパラメータとして伝えました.
function jsCall(oThis) { //   jsCall  Call    
	var argsNew = [].slice.call(arguments, 1) return this.apply(oThis, argsNew);
}
Function.prototype.jsCall = jsCall;
function f1(a) {
	alert([this, a, 'f1']);
}
function f2(a) {
	alert([this, a, 'f2']);
}
f2.apply(11); //11,,f2
 
戻りの結果はf 1.jsCall.jsCall(f 2,11)と同じです.
振り返って見ると
function f1() {
	alert(1);
}
function f2() {
	alert(2)
}
var f3 = f1.call;
f1.call(f2); //1
f3.call(f2);//2
 
このようにして、f 1.cal.call(f 2)が実現されると、f 1.cal実行中にcallのthisがf 2に置換されます.f 2にはthisの引用がないので、実行結果は2.
f2.call()//2
 
注意したいのは、f 1.callの場合とは違います.f 1は関数オブジェクトです.
回転:http://hszy00232.blog.163.com/blog/static/43022753201131835653841/