私たちのベテランの先人たちは、数え切れないほどのコードを書き、数え切れないほどの落とし穴に陥ってきました。しかし、ビジネスコードでは決して起こらない落とし穴がいくつかあるので、人生では決して踏み込んだり触れたりしないかもしれません~~ 1Function.prototype は実際には関数型です。カスタム関数のプロトタイプはオブジェクト型です。 typeof Function.prototype === 'function'; // true 関数 People() {} typeof People.prototype === 'object'; // true したがって、次のように空の関数を設定できます。 // わかりました const noop = Function.prototype; // わかりました 定数 noop = () => {}; 2変数が本当にそれ自身と等しくないことはあり得るのでしょうか? 定数x = NaN; x !== x // 真 これは、今のところ js 言語でそれ自身と等しくない唯一のデータです。なぜ? NaN は特定の値ではなく範囲を表すためです。 isNaN('abc'); // 真 Number.isNaN('abc') // false したがって、古いブラウザとの互換性を維持したい場合は、 x !== x を使用して NaN かどうかを判断するのが適切な解決策です。 3コンストラクタが新しいデータを返す場合 // 関数 People() を返さない {} const people = new People(); // 人 {} // 数値を返す function People() { 1 を返します。 } const people = new People(); // 人 {} // 新しいオブジェクトを返す function Animal() { 戻る { こんにちは世界'、 }; } const animal = new Animal(); // { hello: 'world' } コンストラクタをインスタンス化するときに、非オブジェクト型を返すと動作しません。 4.call.call 誰を応援してるの? 関数fn1() { コンソールログ(1); } 関数fn2() { コンソールログ(2); } fn1.call.call(fn2); // 2 したがって、fn1.call.call(fn2) は fn2.call(undefined) と同等です。 .call をいくつ追加しても、効果は同じです。 5インスタンス化されたオブジェクトを再度インスタンス化できますか? 関数 People() {} const lili = new People(); // People {} const lucy = new lili.constructor(); // 人 {} lili のプロトタイプ チェーンは People プロトタイプを指しているため、プロパティを上方向に検索すると、最終的に Peopel.prototype 上のコンストラクターである People 自体が見つかります。 6setTimeout をネストすると、どのような奇妙なことが起こりますか? コンソールログ(0, Date.now()); タイムアウトを設定する(() => { コンソールログ(1, Date.now()); タイムアウトを設定する(() => { コンソールログ(2, Date.now()); タイムアウトを設定する(() => { コンソールログ(3, Date.now()); タイムアウトを設定する(() => { コンソールログ(4, Date.now()); タイムアウトを設定する(() => { コンソールログ(5, Date.now()); タイムアウトを設定する(() => { コンソールログ(6, Date.now()); }); }); }); }); }); }); レイヤー 0 ~ 4 では、setTimeout 間隔は 1 ミリ秒ですが、レイヤー 5 では間隔は少なくとも 4 ミリ秒です。 7デフォルトパラメータを持つes6関数は宣言スコープを生成します var x = 10; 関数 fn(x = 2, y = 関数 () { 戻り値 x + 1 }) { var x = 5; y() を返します。 } fn(); // 3 8関数式(非関数宣言)内の関数名は上書きできません 定数 c = 関数 CC() { CC = 123; CC を返します。 }; c(); // 関数 もちろん、var CC = 123 を設定した場合は、宣言キーワードを追加することで上書きできます。 9厳密モードでは、関数のthisはWindowではなくundefinedになります。 // 非厳密関数 fn1() { これを返します。 } fn1(); // ウィンドウ // 厳密な関数 fn2() { '厳密な使用'; これを返します。 } fn2(); // 未定義 webpack によってパッケージ化されたモジュール化されたコードは、基本的に厳密モードのコードです。 10丸め演算はビット演算を使用して行うこともできる。 var x = 1.23 | 0; // 1 ビット演算では 32 ビットの整数のみがサポートされるため、小数点はすべて破棄されます。 11indexOf() は数値を比較する必要がなくなりました 定数arr = [1, 2, 3]; // 存在する、> -1 と同等 (〜arr.indexOf(1))の場合{ } // 存在しない、=== -1 と同等 !~arr.indexOf(1); ビット演算はより効率的になり、コードはより簡潔になります。 es6 の include() も使用できます。ただし、オープンソース ライブラリを作成するときに互換性を考慮する必要がある場合は、indexOf を使用することをお勧めします。 12ゲッター/セッターも動的に設定できますか? クラスHello { _name = 'ルーシー'; 取得名() { this._name を返します。 } // 静的ゲッター IDを取得する() { 1 を返します。 } } 定数 hel = 新しい Hello(); hel.name; // 未定義 hel.getName(); // ルーシー // 動的ゲッター Hello.prototype.__defineGetter__('name', function() { this._name を返します。 }); Hello.prototype.__defineSetter__('name', 関数(値) { this._name = 値; }); hel.name; // ルーシー hel.getName(); // ルーシー hel.name = 'ジミ'; hel.name; // ジミ hel.getName(); // ジミ 130.3 - 0.2 !== 0.1 // 真 浮動小数点演算は正確ではありませんが、これはよくあることですが、誤差は許容範囲内です。 0.3 - 0.2 - 0.1 <= Number.EPSILON // 真 14クラス構文シュガーはどのように継承されますか? 関数Super() { 1 を返します。 } 関数Child() { // プロパティ継承 Super.call(this); 2 を 0 にします。 } // プロトタイプ継承 Child.prototype = new Super(); 定数child = 新しいChild(); 子.a; // 1 正式なコードのプロトタイプ継承では、親クラスを直接インスタンス化するのではなく、動的プロパティの繰り返し宣言を避けるために空の関数をインスタンス化します。 const extends = (Child, Super) => { 定数fn = 関数(){}; fn.prototype = スーパープロトタイプ; Child.prototype = 新しい fn(); Child.prototype.constructor = Child; }; 15es6は実際にオブジェクトを繰り返し分解することができます 定数オブジェクト = { a: { 1 です }, 2: 2 です }; 定数 a: { b }, a } = obj; 1 行のコードで a と ab の両方が取得されます。 16コードが圧縮されているかどうかを判断するのはとてもクールです 関数 CustomFn() {} const isCrashed = typeof CustomFn.name === 'string' && CustomFn.name === 'CustomFn'; 17オブジェクト === はメモリアドレスを比較し、 >= は変換された値を比較します。 {} === {} // 偽 // 暗黙的な変換 toString() {} >= {} // 真 18intanceofの判定方法は、プロトタイプが現在のオブジェクトのプロトタイプチェーン上にあるかどうかである。 関数 People() {} 関数 Man() {} Man.prototype = 新しい People(); Man.prototype.constructor = Man; man を新しい Man() に追加します。 man instanceof People; // true //People のプロトタイプを置き換えます People.prototype = {}; man instanceof People; // false es6クラスを使用する場合、プロトタイプprototypeは再定義できないため、上記のような状況は発生しません。 19Object.prototype.__proto__ === null; // true これはプロトタイプチェーンの最上位レベルであり、nullである。 20数値が小さすぎるとparseIntはバグを引き起こします parseInt(0.00000000454); // 4 parseInt(10.23); // 10 211 + ヌル // 1 1 + 未定義 // NaN 数値(null) // 0 数値(未定義) // NaN 22実際のパラメータと形式パラメータは同期関係を維持する 関数テスト(a, b, c) { console.log(a, b, c); // 2, 3, 未定義 引数[0] = 100; 引数[1] = 200; 引数[2] = 300; console.log(a, b, c); // 100、200、未定義 } テスト(2, 3); 渡される実際のパラメータの数が不十分な場合、同期関係も失敗します。 23ボイドは頑固な老人だ void 0 === 未定義 // 真 void 1 === 未定義 // 真 void {} === 未定義 // true void 'hello' === 未定義 // true void void 0 === 未定義 // true 誰も誰とも関係ないよ〜〜 24try/catch/finallyにも特定の実行順序がある 関数fn1() { コンソールログ('fn1'); 1 を返します。 } 関数fn2() { コンソールログ('fn2'); 2を返します。 } 関数 getData() { 試す { 新しいエラーをスローします(''); } キャッチ (e) { fn1() を返します。 ついに fn2() を返します。 } } コンソールにログ出力します。 // 印刷順序: 'fn1'、'fn2'、2 try/catch コード ブロックで return xxyyzz; キーワードに遭遇すると、最初に xxyyzz が実行され、その値が一時変数に配置されます。次に、finally コード ブロックの内容が実行され、一時変数が返されます。 25複数の数値に等しい変数 x はありますか? 定数x = { 値: 0, 文字列を渡す ++this.value を返します。 } } x == 1 && x == 2 && x == 3; // 真 暗黙的な変換を使用すると、これは難しいことではありません。 26clearTimeout と clearInterval は互換的に使用できますか? var タイムアウト = setTimeout(() => console.log(1), 1000); var 間隔 = setInterval(() => console.log(2), 800); クリアインターバル(タイムアウト); clearTimeout(間隔); 答えは「はい」です。ほとんどのブラウザは相互クリーンアップ タイマーをサポートしていますが、対応するクリーンアップ機能を使用することをお勧めします。 27以下の印刷順序は何ですか? タイムアウトを設定する(() => { コンソールログ(1); }, 0); 新しいPromise((resolve) => { コンソールログ(2); 解決する(); }).then(() => console.log(3)); 関数callMe() { コンソールログ(4); } (非同期() => { callMe() を待機します。 コンソールログ(5); })(); 答えは、2、4、3、5、1です。 メインクエスト: 2、4 28null はオブジェクト型ですが、Object から継承されません。これは歴史的なバグのようなものです。非常に多くの人がこの機能を使用していたため、これを修正すると何千ものプログラムが壊れてしまいます。 typeof null === 'object'; // true Object.prototype.toString.call(null); // [オブジェクト Null] null インスタンスオブオブジェクト; // false 29基本型 (null と undefined を除く) を操作する場合、エンジンは自動的にデータをオブジェクトにパッケージ化し、操作後にオブジェクトを破棄します。 'abc'.substr(1); (123)固定(2) したがって、プロトタイプチェーンが変更されない限り、追加されたデータは破棄されます。 定数データ = 'abc'; データ.x = 'y'; console.log(data.x); // 未定義 データ.__proto__.x = 'z'; console.log(data.x); // 'z' 30安全値を超えるとデータは安全ではなくなる Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // 真 // 2 ** 53 === 2 ** 53 + 1 と同等です。// true 31関数パラメータにデフォルト値があると、認識が変わる 関数テスト(a, b = 1) { // エイリアス同期、非厳密モードでは同期されることが期待されます arguments[0] = 20; コンソールログ(a); // 2 } // 関数パラメータの数を確認します。期待値は 2 です。 console.log(テストの長さ); // 1 テスト(123); 32数値はすべて浮動小数点型です。ビット演算を実行する場合、js はまず数値を int 型に変換します。他の言語と比較すると、これは追加のパフォーマンスオーバーヘッドになります。 1 | 0 // 1 1.234 | 0 // 1 1.234 | 0.6 // 1 1 & 1 // 1 1.23 & 1.456 // 1 ~1 // -2 ~1.234 // -2 33場所への割り当ては直接ジャンプできる 場所 = 'http://baidu.com'; 34「new」の別の使い方を知っていますか? 関数テスト() { console.log(new.target === Test); // true } 新しいテスト(); サブクラスがインスタンス化されている場合、new.target は Test ではありません。このメソッドは抽象クラスの効果を実現できます。 35+0と-0には違いがある 1/+0 === 無限大 1/-0 === -無限大 以上がJavascriptの変な知識の詳細ですが、ご存知ですか?JavaScriptの変な知識の詳細については、123WORDPRESS.COMの他の関連記事に注目してください! 以下もご興味があるかもしれません:
|
<<: MySQLクエリプランでken_lenの値を計算する方法
>>: Docker Toolboxを完全にアンインストールする方法
この質問は非常に奇妙なので、あまり多くを語らずにコードに直接進みます。 .g-ダイアログラッパー{ ...
目次1. インスタンスをインストールして作成する2. vue-router4の新機能2.1 動的ルー...
目次1. React フックと純粋関数2. シンプルなmyUseState 3. myUseStat...
VMware をインストールして新しい仮想マシンを作成したら、オプション バーの [編集] - [仮...
複数テーブルクエリ複数のテーブルから関連するクエリ結果を取得するには、単一の SELECT ステート...
SSHFS の機能: FUSE(Linux向けの最高のユーザー空間ファイルシステムフレームワーク)を...
Nginx 仮想ドメイン名設定を使用すると、ドメイン名を購入せずに特定のドメイン名を介してローカル ...
ブログの正式名称は「Web log」で、中国語で「ネットワークログ」を意味します。後にブログに短縮さ...
目次1. ハッシュテーブルの原理2. ハッシュテーブルの概念3. ハッシュ競合問題1. チェーンアド...
SEO とセキュリティを考慮して、301 リダイレクトが必要です。以下の一般的な処理には Nginx...
目次1. 使いやすい2. 関数内でジェネリックを使用する3. クラス内でジェネリックを使用する4. ...
問題の説明(キープアライブとは何か)キープアライブ 名前の通り、アクティブな状態を維持します。誰が活...
静的ウェブサイトをホストできるサーバーは数多くあります。この記事では、nginx、apache、to...
Nginx Rewriteの使用シナリオ1. URL アドレスジャンプ。たとえば、ユーザーが pm....
Tomcat は Java 言語をベースにした Web サーバー ソフトウェアです。この記事では主に...