興味深い JS コード行

coldplay.xixi
リリース: 2020-10-29 17:07:42
転載
2170 人が閲覧しました

フレーム クラスのソース コードには、次のようなコードがよく見られます。一句コード、例:

var toStr1 = Function.prototype.call.bind(Object.prototype.toString);复制代码
ログイン後にコピー
興味深い JS コード行 この一句コードでは call メソッドが使用され、同時にbind メソッドも使用されています。以下を参照してください。さまざまなタイプの実験を導入すると、結果は次のようになります。
console.log(toStr1({}));      // "[object Object]"console.log(toStr1([]));      // "[object Array]"console.log(toStr1(123));     // "[object Number]"console.log(toStr1("abc"));   // "[object String]"console.log(toStr1("abc"));   // "[object String]"console.log(toStr1(new Date));// "[object Date]"复制代码
ログイン後にコピー

結果から、このアプローチの主な機能は、対象のタイプを検出することにあることがわかります。さらに多くの場合、次のようなコードが見られます。

var toStr2 = obj => Object.prototype.toString.call(obj);console.log(toStr2({}));      // "[object Object]"console.log(toStr2([]));      // "[object Array]"console.log(toStr2(123));     // "[object Number]"console.log(toStr2("abc"));   // "[object String]"console.log(toStr2("abc"));   // "[object String]"console.log(toStr2(new Date));// "[object Date]"复制代码
ログイン後にコピー

熟達バインドと呼び出しの同じ知識です。どちらの方法も本質的には同じですが、2 番目の方法のより厳密な点は、1 回の呼び出し機能のみを使用することです。望ましい機能であり、暗号化されていますが、より簡単に、複数のフレームで最初の機能を使用できるのはどれですか?私たちがトラフィック コードに

Object.prototype.toString

メソッドをオーバーライドしたように、2 番目の書き込み方法では正しい結果が得られませんが、最初の書き込み方法では正しい結果が得られます。

var toStr1 = Function.prototype.call.bind(Object.prototype.toString);var toStr2 = obj => Object.prototype.toString.call(obj);Object.prototype.toString = function(){  return'toString方法被覆盖!';
}// 接着我们再调用上述方法// toStr1调用结果如下:console.log(toStr1({}));      // "[object Object]"console.log(toStr1([]));      // "[object Array]"console.log(toStr1(123));     // "[object Number]"console.log(toStr1("abc"));   // "[object String]"console.log(toStr1("abc"));   // "[object String]"console.log(toStr1(new Date));// "[object Date]"// toStr2调用结果如下:console.log(toStr2({}));      // "toString方法被覆盖!"console.log(toStr2([]));      // "toString方法被覆盖!"console.log(toStr2(123));     // "toString方法被覆盖!"console.log(toStr2("abc"));   // "toString方法被覆盖!"console.log(toStr2("abc"));   // "toString方法被覆盖!"console.log(toStr2(new Date));// "toString方法被覆盖!"复制代码
ログイン後にコピー

結果は明らかです。最初の方法は結果を得ることができましたが、2 番目の方法は実行されませんでした。呢?我们知道バインド関数返還結果は 1 つの関数です、この関数は関数内部の関数です、延長される可能性があります、那么很自然にここに存在する可能性があります闭パック!状態 #。 次世代版ブラウザの呼び出しとバインドの両方が js の内部で実現されているわけではありませんが、法的な調整は行っていません。これは本文のデモです、大家可以下:

// 模拟实现call// ES6实现Function.prototype.mycall = function (context) {
  context = context ? Object(context) : window;  var fn = Symbol();
  context[fn] = this;  let args = [...arguments].slice(1);  let result = context[fn](...args);  delete context[fn]  return result;
}// 模拟实现bindFunction.prototype.mybind = function (context) {  if (typeof this !== "function") {    throw new Error("请使用函数对象调用我,谢谢!");
  }  var self = this;  var args = Array.prototype.slice.call(arguments, 1);  var fNOP = function () { };  var fBound = function () {    var bindArgs = Array.prototype.slice.call(arguments);    return self.myapply(this instanceof fNOP ? this : context, args.concat(bindArgs));
  }

  fNOP.prototype = this.prototype;
  fBound.prototype = new fNOP();  return fBound;
}// 模拟实现apply// ES6实现Function.prototype.myapply = function (context, arr) {
    context = context ? Object(context) : window;    var fn = Symbol();
    context[fn] = this;    let result;    if (!arr) {
        result = context[fn]();
    } else {
        result = context[fn](...arr);
    }    delete context[fn]    return result;
}var toStr1 = Function.prototype.mycall.mybind(Object.prototype.toString);console.log(toStr1({}));      // "[object Object]"console.log(toStr1([]));      // "[object Array]"console.log(toStr1(123));     // "[object Number]"console.log(toStr1("abc"));   // "[object String]"console.log(toStr1(new Date));// "[object Date]"复制代码
ログイン後にコピー

興味深い JS コード行

上述的实现略去一些健壮性的代码,仅保留核心逻辑,具体的实现细节这里不做解释,有兴趣的可以自己研究,从devtools我们看到mybind形成的闭包确实在函数对象toStr1的作用域上!

当然如果你对原型链有深刻理解的话,其实这句有趣的代码还可以写成如下方式:

var toStr3 = Function.call.bind(Object.prototype.toString);var toStr4 = Function.call.call.bind(Object.prototype.toString);var toStr5 = Function.call.call.call.bind(Object.prototype.toString);// 甚至可以这么写。。。var toStr6 = (()=>{}).call.bind(Object.prototype.toString);复制代码
ログイン後にコピー

-END-

相关免费学习推荐:javascript(视频)

以上が興味深い JS コード行の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.im
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート