手書きコール
call callとapplyの違い:callメソッドはパラメータのリストを受け取り、applyメソッドは複数のパラメータを含む配列を受け取る。
- 1. コンテキストが存在する場合はそれを使用し、そうでない場合はウィンドウを使用します。
- 3.ループのパラメータ。最初から、最初にコンテキストがあり、その後に必要なパラメータが続くことに注意してください。
- パラメータ文字列をargsにプッシュ
- 5.文字列と配列をスプライスする場合、配列はtoStringメソッドを呼び出すので、パラメータを1つずつ渡してevalで実行することができます。
- 6.結果を返す前にfnを削除します。
Function.prototype.call = function(context) {
context = context ? Object(context) : window;
context.fn = this;
let args = [];
for (let i = 1; i < arguments.length; i++) {
args.push('arguments['+ i +']');
}
let res = eval('context.fn('+ args +')');
delete context.fn;
return res;
}
手書きアプリケーション
- 1.applyは、引数のリストをループする必要をなくします;渡された引数は配列です。
- 2.ただし、argsはオプションのパラメータなので、渡さなければそのまま実行されます。
Function.prototype.apply = function(context, args) {
context = context ? Object(context) : window;
context.fn = this;
if (!args) {
return context.fn();
}
let res = eval('context.fn('+ args +')');
delete context.fn;
return res;
}
手書きバインド
- 1.バインドのパラメータは、バインド時と呼び出し時に2回渡すことができます。
- 2. bindArgsはバインド時に渡される最初のパラメータ以外のパラメータ、argsは呼び出し時に渡されるパラメータで、2つをつなげて渡します。
- 3.バインディング関数がnew演算子を用いて構築された場合、thisポインティングは変更され、thisは現在のインスタンス
- 4.Fnを通してプロトタイプをリンクし、fBoundがプロトタイプチェーンを通して親Fnのプロパティにアクセスできるようにします。
Function.prototype.bind = function(context) {
let that = this;
let bindArgs = Array.prototype.slice.call(arguments, 1);
function Fn () {};
function fBound(params) {
let args = Array.prototype.slice.call(arguments) ;
return that.apply(this instanceof fBound ? this : context, bindArgs.concat(args));
}
Fn.prototype = this.prototype;
fBound.prototype = new Fn();
return fBound;
}
手書きの new
- 1.コンストラクタはnewに渡される最初の引数で、残りの引数はその他の引数です。
obj.__proto__ = Constructor.prototype
2.プロトタイプからメソッドを継承するために使用します。- 3.残りの引数をコンストラクタに渡し、thisをobjにバインドし、実行します。
- 4.コンストラクタが参照型を返す場合は、参照型が直接返され、そうでない場合は obj が返されます。
const myNew = function() {
let Constructor = Array.prototype.shift.call(arguments);
let obj = {};
obj.__proto__ = Constructor.prototype;
let res = Constructor.apply(obj, arguments);
return res instanceof Object ? res : obj;
}
手書きのinstanceOf
- 1.左のプロトタイプ・チェーンを調べて、プロトタイプのどれかがプロトタイプと等しいかどうかを確認します。
- 2.境界条件を決定し、左=== nullの場合、つまり、右===左、つまり、trueのリターンを見つけるために、頭がfalseを返さなかった見つけることです。
- 3.左 = 左.__プロト__、上を見続ける
const myInstanceof = function(left, right) {
right = right.prototype;
left = left.__proto__;
while (true) {
if (left === null) {
return false;
}
if (right === left) {
return true;
}
left = left.__proto__;
}
}
手書きオブジェクト.create
- 新しい空のコンストラクタFを作成し、F.prototypeがobjを指すようにして、最後にFのインスタンスを返します。
const myCreate = function (obj) {
function F() {};
F.prototype = obj;
return new F();
}