原生jsはbind、call、appyを実現します.
オリジナルJavaScriptを使用したアナログ実装:
まず、この3つは全部は例を挙げます. 私たちが ですので、 では、賦課後のthisの指し方が変わらないことをどう保証しますか?
咳(無駄口ing—上から持ち上げます):
優秀なプログラマは、もちろん表面に流れてはいけません.APIを呼び出すと同時に、私たちも考えてみたいです.もし自分でこの三つのAPIを書いたら、どうやってそれらの効果を実現しますか?
原生js実現bind:は このゲームは、すべての関数の祖先であり、いずれかのJavaScript関数は、実際には 大域の もしあなたがプロトタイプチェーンをよく理解していないなら、私が説明を簡単にします. のすべての関数と で、このチェーンは ですので、簡単に言えば、私たちの関数ごとに呼び出される方法を実現するには、
ちょっと言ってください. Object.create()方法は、新たに作成されたオブジェクトを既存のオブジェクトを使用して提供する新しいオブジェクトを作成する.proto_ は、オブジェクトを継承し、オブジェクトの属性をオブジェクトのプロトタイプの下に追加することができるという簡単な理解ができる. 以下、具体的にビッドコードを実現することを見ます.まず、ビッドがn個のパラメータを受信することを知っています.2種類のものに分けられます. 第一類:つまり、bindの最初のパラメータであり、必須のパラメータであり、thisの正確な方向を指す. 第二類:私たちが伝えたい他のパラメータ. コードの中で、後のすべての送信のパラメータを、S 6の拡張演算子を使用して、統一的に に続いて、現在のthisを保存します.この時、thisは関数get Nameを指します. 次いで、 は上のビッドの例を観察することによって、ビッド動作が最後に戻ったのは関数であることが分かります.だから、私たちは追加の変数を定義して受信-呼び出しを受ける必要があります.
豆知識: は、関数呼び出し時にパラメータを伝えることができるということを知っていますが、 は、上記の例でこの動作を行ったと仮定します. これにより、私たちはまた、マイビドーFunで伝達されたパラメータを受け取る必要があり、同じくEs 6の拡張演算子で この時、私達が理解したいのは、このmyBindFunは誰を指していますか? はmyBindFun内部に入ります.まずこのthisを判断します.現在の例ですか?
instance解釈:
例えば、 どうしてこの判断を行いますか?関数を呼び出すときはnewの場合がありますので、例を挙げてください. このとき、 これは問題があります.元々はクローズドの場合、 ですので、私たちはこの状況を排除したいので、 もしそうであれば、現在の は次に、 最後に、もう一つの点があります. テスト:
callとappyの実現について、次のブログで話しています.転送ゲート:元生jsシミュレーションでbind call appyを実現します.
bind
call
apply
.まず、この3つは全部
this
の指し示しを変えるためのものです.ほとんどの人はbind
の使用に慣れていないと信じています.他の2つについて分からないことがあれば、私のブログを見に行きます.JavaScriptのcallとappy()this.name = 81;
var obj = {
name: 9,
getName:function(){
console.log(this.name);
}
}
obj.getName();
// 9 【this obj】
var res = obj.getName;
res();
// 81 【this window】
はなぜこのような違いが生じたのですか?obj.getName
をグローバル変数に与えたとき、彼のthisはobjを指すことからwindowを指すようになりました.this.name
は81を出力します.// bind
var res = obj.getName.bind(obj);
res();
// call
obj.getName.call(obj);
// apply
obj.getName.apply(obj);
にはこの3つの方法があります.thisの指摘問題を簡単に修正できます.なお、callとappyは直接呼び出しを行い、変数受信を定義する必要はなく、bindとは少し違っています.咳(無駄口ing—上から持ち上げます):
優秀なプログラマは、もちろん表面に流れてはいけません.APIを呼び出すと同時に、私たちも考えてみたいです.もし自分でこの三つのAPIを書いたら、どうやってそれらの効果を実現しますか?
原生js実現bind:
Function
と言ってください.Function
オブジェクトです.Function
オブジェクトには独自の属性と方法がないが、それ自体も関数であるため、プロトタイプチェーンを介して自身のプロトタイプチェーンFunction.prototype
からいくつかの属性と方法を継承することもある.【MDNから来た】Function
という祖先との間には密接な関係があり、チェーンが互いに繋がっているようです.__proto__
で、__proto__
はFunction
のprototypre
を指しています.Function.prototype
はこのゲーム自体がFunction
です.Function.prototype
上でしかないです.何しろ祖先です.私たちが定義した関数は、プロトタイプチェーンを通して見つけられ、それを実現することができます.// Function myBind
Function.prototype.myBind = function(){
};
var a = {
name:'syw'};
var b = Object.create(a);
console.log(b); // {}
console.log(b.__proto__); // {name:'syw'}
console.log(b.name); // syw
コード解説:var obj = {
name: 9,
getName:function(){
console.log(this.name);
}
}
// Function myBind
Function.prototype.myBind = function (objThis, ...params) {
//
const this_copy = this;
let myBindFun = function (...params2) {
// , this 。【 】
const isNew = this instanceof myBindFun;
const thisArg = isNew ? this : objThis;
return this_copy.call(thisArg, ...params, ...params2);
}
// myBindFun ,
myBindFun.prototype = Object.create(this_copy.prototype);
return myBindFun;
}
var res = obj.getName.bind(obj);
res(); // 9
Object.create()
を受信しました....params
関数を定義した.豆知識:
myBindFun
はどうなりますか?// :function.bind(thisArg[, arg1[, arg2[, ...]]])
obj.getNmae.bind(obj,1,2,3);
// obj
// 1 2 3
は bind ,
関数でgetName
を印刷したら、パラメータが統合されています.arguments
を受信することができる....params2
var res = obj.getName.bind(obj,1,2,3);
res(4,5,6);
なぜですか?それとも閉じますか?興味があります.このコードを実行してください.console.log(myBindFun.prototype); // :getName {}
instance解釈:
例えば、
myBind myBind ,myBindFun
は同じ場所を指すかどうか.a instance b a.__proto__ b.prototype
時new res()
の関数内部のthisは、調整者myBindFun
とgetName
の指向が同じである.myBindFun.prototype
関数内部のmyBindFun
はthis
オブジェクトを指すべきです.window
を使用して、現在のthis instaceof myBindFun
が同じ場所を指すかどうかを検出します.this.__proto__
をそのまま使用し、存在しない場合は、着信myBindFun.prototype
を使用する.this
を通じて、私たちが最初に保存したthisの方向を変更し、パラメータを呼び出して、それを返します.function syw(a){
console.log('this1',this);
return function(b){
console.log('this2',this);
return a + b;
}
}
const a = syw(2);
console.log('a: ', a); // a return
const b = a(1);
console.log('b', b); // b 3
const c = new a(1);
console.log('c', c); // c {}
// :new a(1) , c {}
objThis
は父の構造関数のすべての属性を継承することに相当します.ですから、call
を通じてobj.bind(obj)
の中のすべての属性を継承していく必要があります.let res = obj.getName.myBind(obj);
new res(); //【 :res myBind】
// this.name undefined
はい、これで終わります.callとappyの実現について、次のブログで話しています.転送ゲート:元生jsシミュレーションでbind call appyを実現します.