ホームページ  >  記事  >  ウェブフロントエンド  >  新しいことについて、バグから始めましょう

新しいことについて、バグから始めましょう

一个新手
一个新手オリジナル
2017-09-26 10:30:251318ブラウズ


前書き

今日、フロントエンドグループで、誰かが質問を投稿しているのを見ました:

var o = new Object();function foo(obj){
    var obj = o;
    obj.name = '123';
    obj = new Object();
    obj.name = '456';
}
foo(o);
console.log(o.name)

上記のコードに示されているように、条件やデータを変更せずに「456」を出力することは可能ですか?

グループの人々が結論に飛びつき始めるまでに時間はかかりませんでしたが、通常の状況ではそんなことはできません。

その理由は? 参照型の使用方法を少しでも知っている人なら、 new Object() が obj のポインターを変更し、決して取得できないことを知っています 456


問題は

通常の状況では456を出力することは不可能です。では、どのようなエラー条件下では456が出力されるでしょうか。結局のところ、プログラマはバグを書くのが得意であり、異常な状況を引き起こすことができるはずです。

そのとき、障害のある私は、2日前に学んだばかりのProxyのことを突然思い出しました。値を割り当てるときに問題が発生しました。メタデータから問題を解決できるでしょうか?試してみてください:

//demo_01var o = new Object();
o = new Proxy(o,{    
    set(target, key, value,receiver){        
    if(Object.is('name',key))            
    return Reflect.set(target, key, `456`,receiver);        
    return Reflect.set(target, key, value , receiver);
    }
})function foo(obj){
    var obj = o;
    obj.name = '123';
    obj = new Object();
    obj.name = '456';
}
foo(o);
console.log(o.name)

完璧に、正常に 456 を出力しました。

何?プロキシとは何かご存知ですか?ここをクリック –> ES6 インターセプター、プロキシ

それでは、結果をグループに送信して披露してみましょう。まずはチャット履歴を見てみましょう。ふふ、私よりも早く答えている人がいます。さて、最初に他の人の答えを見てみましょう:

//demo_02var o = new Object();Object.defineProperty(o,'name',{
    set(val){        this.value = '456';
    },
    get(){        return this.value;
    }
})function foo(obj){
    var obj = o;
    obj.name = '123';
    obj = new Object();
    obj.name = '456';
}
foo(o);
console.log(o.name)

素晴らしい若者、一緒に行こうと思いました。彼らは全員ゲッターとセッターに取り組んでおり、メタレベルでデータを処理しています。

このクラスメートは、ここからインスピレーションを得たという記事を同時に投稿しました。これは本当に完璧なフックです

次に、私の答えも投稿します。つまり、その時の楽しみに参加するだけです。待て、一部の人は不満を表明し、彼は日和見的だと言っていた。 demo_02 コードは、demo_03 コードと完全に同等です:

//demo_03var o = new Object();function foo(obj){
    var obj = o;
    obj.name = '123';
    obj = new Object();
    obj.name = '456';
}
foo(o);
o.name = '456';
console.log(o.name);

demo_02 メソッドのコード「obj.name = '456';」が変更されると、デモ_02 コードもそれに応じて変更する必要があります。

それは当然のことです。私が作成したデモ_01 にも同じ問題があります。そうでなければ、恥ずかしい思いをするでしょう。
それでは、この問題を解決して実際の出力を実現する方法はあるのでしょうか456


新しい演算子は何をするのでしょうか?

ところで、私たちの今の問題は何ですか?問題は、obj の this ポインタを変更する new Object() 上にあることです。これを回避する方法はありますか?

何?なぜこのポインタが変わったのかというと、この記事をよく見てください。兵士から始めて、New が何をしたかを覚えています。 Proxy ハンドラーに構築メソッドがあることを確認します。これを Object コンストラクターで変更できます。アイデアは良かったのですが失敗し、実現しませんでした。このアイデアを続けられる人がいたら、答えを教えてください>_< チャット履歴を見ると、クラスメートは別の解決策を示しました:

var o = new Object();var _Object = Object;Object = function(){
    return o;
}function foo(obj){
    var obj = o;
    obj.name = &#39;123&#39;;
    obj = new Object();
    obj.name = &#39;456&#39;;
}

foo(o);
console.log(o.name)Object = _Object;

今回は、クラスメートがオブジェクトを最初に書き換えて、オブジェクト o を返します。あなたはとても才能のある人です、私はあなたを尊敬します。黙って集める<_<

頑張れ、必ず何かを教えてくれる人がいるよ

以上が新しいことについて、バグから始めましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。