1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        JavaScript 里的奇葩知識,你遇到過嗎?

        共 6134字,需瀏覽 13分鐘

         ·

        2020-10-15 19:43

        作者:原罪
        https://segmentfault.com/a/1190000023941089

        久經(jīng)沙場的前輩們,寫了無數(shù)代碼,踩了無數(shù)的坑。但有些坑,可能一輩子也踩不到摸不著,因為根本不會發(fā)生在業(yè)務代碼里~~

        1

        Function.prototype?竟然是個函數(shù)類型。而自定義函數(shù)的原型卻是對象類型。

        typeof?Function.prototype?===?'function';??//?true

        function?People()?{}
        typeof?People.prototype?===?'object';??????//?true

        所以我們設置空函數(shù)可以這么做:

        //?Good?
        const?noop?=?Function.prototype;

        //?Bad
        const?noop?=?()?=>?{};

        2

        一個變量真的會不等于自身嗎?

        const?x?=?NaN;
        x?!==?x??//?true

        這是目前為止 js 語言中唯一的一個不等于自己的數(shù)據(jù)。為什么?因為?NaN?代表的是一個范圍,而不是一個具體的數(shù)值。在早期的?isNaN()?函數(shù)中,即使傳入字符串,也會返回?true?,這個問題已經(jīng)在 es6 中修復。

        isNaN('abc');???????//?true
        Number.isNaN('abc')?//?false

        所以如果您想兼容舊瀏覽器,用?x !== x?來判斷是不是NaN,是一個不錯的方案。

        3

        構造函數(shù)如果?return了新的數(shù)據(jù)

        //?不返回
        function?People()?{}
        const?people?=?new?People();???//?People?{}

        //?返回數(shù)字
        function?People()?{
        ??return?1;
        }
        const?people?=?new?People();???//?People?{}

        //?返回新對象
        function?Animal()?{
        ??return?{
        ????hello:?'world',
        ??};
        }
        const?animal?=?new?Animal();??//?{?hello:?'world'?}

        在實例化構造函數(shù)時,返回非對象類型將不生效

        4

        .call.call?到底在為誰瘋狂打call?

        function?fn1()?{
        ??console.log(1);
        }

        function?fn2()?{
        ??console.log(2);
        }

        fn1.call.call(fn2);?//?2

        所以?fn1.call.call(fn2)?等效于?fn2.call(undefined)。而且無論您加多少個?.call,效果也是一樣的。

        5

        實例后的對象也能再次實例嗎?

        function?People()?{}

        const?lili?=?new?People();????????????//?People?{}
        const?lucy?=?new?tom.constructor();???//?People?{}

        因為?lili?的原型鏈指向了?People?的原型,所以通過向上尋找特性,最終在?Peopel.prototype?上找到了構造器即?People?自身

        6

        setTimeout?嵌套會發(fā)生什么奇怪的事情?

        console.log(0,?Date.now());

        setTimeout(()?=>?{
        ??console.log(1,?Date.now());
        ??setTimeout(()?=>?{
        ????console.log(2,?Date.now());
        ????setTimeout(()?=>?{
        ??????console.log(3,?Date.now());
        ??????setTimeout(()?=>?{
        ????????console.log(4,?Date.now());
        ????????setTimeout(()?=>?{
        ??????????console.log(5,?Date.now());
        ??????????setTimeout(()?=>?{
        ????????????console.log(6,?Date.now());
        ??????????});
        ????????});
        ??????});
        ????});
        ??});
        });

        在0-4層,setTimeout?的間隔是?1ms?,而到第 5 層時,間隔至少是?4ms?。

        7

        es6函數(shù)帶默認參數(shù)時將生成聲明作用域

        var?x?=?10;

        function?fn(x?=?2,?y?=?function?()?{?return?x?+?1?})?{
        ??var?x?=?5;
        ??return?y();
        }

        fn();???//?3

        8

        函數(shù)表達式(非函數(shù)聲明)中的函數(shù)名不可覆蓋

        const?c?=?function?CC()?{
        ??CC?=?123;
        ??return?CC;
        };

        c();?//?Function

        當然,如果設置?var CC = 123?,加聲明關鍵詞是可以覆蓋的。

        9

        嚴格模式下,函數(shù)的?this?是?undefined?而不是?Window

        //?非嚴格
        function?fn1()?{
        ??return?this;
        }
        fn1();?//?Window

        //?嚴格
        function?fn2()?{
        ??'use?strict';
        ??return?this;
        }
        fn2();?//?undefined

        對于模塊化的經(jīng)過webpack打包的代碼,基本都是嚴格模式的代碼。

        10

        取整操作也可以用按位操作

        var?x?=?1.23?|?0;??//?1

        因為按位操作只支持32位的整型,所以小數(shù)點部分全部都被拋棄

        11

        indexOf()?不需要再比較數(shù)字

        const?arr?=?[1,?2,?3];

        //?存在,等效于?>?-1
        if?(~arr.indexOf(1))?{

        }

        //?不存在,等效于?===?-1
        !~arr.indexOf(1);

        按位操作效率高點,代碼也簡潔一些。也可以使用es6的?includes()?。但寫開源庫需要考慮兼容性的道友還是用?indexOf?比較好

        12

        getter/setter?也可以動態(tài)設置嗎?

        class?Hello?{
        ??_name?=?'lucy';
        ?
        ??getName()?{
        ????return?this._name;
        ??}
        ??
        ??//?靜態(tài)的getter
        ??get?id()?{
        ????return?1;
        ??}
        }

        const?hel?=?new?Hello();

        hel.name;???????//?undefined
        hel.getName();??//?lucy

        //?動態(tài)的getter
        Hello.prototype.__defineGetter__('name',?function()?{
        ??return?this._name;
        });

        Hello.prototype.__defineSetter__('name',?function(value)?{
        ??this._name?=?value;
        });

        hel.name;???????//?lucy
        hel.getName();??//?lucy

        hel.name?=?'jimi';
        hel.name;???????//?jimi
        hel.getName();??//?jimi

        13

        0.3?-?0.2?!==?0.1??//?true

        浮點操作不精確,老生常談了,不過可以接受誤差

        0.3?-?0.2?-?0.1?<=?Number.EPSILON?//?true

        14

        class?語法糖到底是怎么繼承的?

        function?Super()?{
        ??this.a?=?1;
        }

        function?Child()?{
        ??//?屬性繼承
        ??Super.call(this);
        ??this.b?=?2;
        }
        //?原型繼承
        Child.prototype?=?new?Super();

        const?child?=?new?Child();
        child.a;??//?1

        正式代碼的原型繼承,不會直接實例父類,而是實例一個空函數(shù),避免重復聲明動態(tài)屬性

        const?extends?=?(Child,?Super)?=>?{
        ??const?fn?=?function?()?{};
        ??
        ??fn.prototype?=?Super.prototype;
        ??Child.prototype?=?new?fn();
        ??Child.prototype.constructor?=?Child;
        };

        15

        es6居然可以重復解構對象

        const?obj?=?{
        ??a:?{
        ????b:?1
        ??},
        ??c:?2
        };

        const?{?a:?{?b?},?a?}?=?obj;

        一行代碼同時獲取?a?和?a.b?。在a和b都要多次用到的情況下,普通人的邏輯就是先解構出?a?,再在下一行解構出?b?。

        16

        判斷代碼是否壓縮居然也這么秀

        function?CustomFn()?{}

        const?isCrashed?=?typeof?CustomFn.name?===?'string'?&&?CustomFn.name?===?'CustomFn';

        17

        對象?===?比較的是內存地址,而?>=?將比較轉換后的值

        {}?===?{}?//?false

        //?隱式轉換?toString()
        {}?>=?{}??//?true

        18

        intanceof?的判斷方式是原型是否在當前對象的原型鏈上面

        function?People()?{}
        function?Man()?{}
        Man.prototype?=?new?People();
        Man.prototype.constructor?=?Man;

        const?man?=?new?Man();
        man?instanceof?People;????//?true

        //?替換People的原型
        People.prototype?=?{};
        man?instanceof?People;????//?false

        如果您用es6的class的話,prototype原型是不允許被重新定義的,所以不會出現(xiàn)上述情況

        19

        Object.prototype.__proto__?===?null;?//?true

        這是原型鏈向上查找的最頂層,一個?null

        20

        parseInt?太小的數(shù)字會產(chǎn)生 bug

        parseInt(0.00000000454);??//?4
        parseInt(10.23);??????????//?10

        21

        1?+?null??????????//?1
        1?+?undefined?????//?NaN

        Number(null)??????//?0
        Number(undefined)?//?NaN

        22

        arguments?和形參是別名關系

        function?test(a,?b)?{
        ??console.log(a,?b);?//?2,?3
        ??
        ??arguments[0]?=?100;
        ??arguments[1]?=?200;
        ??
        ??console.log(a,?b);?//?100,?200
        }
        test(2,?3);

        但是您可以用?use strict?嚴格模式來避免這一行為,這樣?arguments?就只是個副本了。

        23

        void?是個固執(zhí)的老頭

        void?0?===?undefined??????????//?true
        void?1?===?undefined??????????//?true
        void?{}?===?undefined?????????//?true
        void?'hello'?===?undefined????//?true
        void?void?0?===?undefined?????//?true

        跟誰都不沾親~~

        24

        try/catch/finally?也有特定的執(zhí)行順序

        function?fn1()?{
        ??console.log('fn1');
        ??return?1;
        }

        function?fn2()?{
        ??console.log('fn2');
        ??return?2;
        }

        function?getData()?{
        ??try?{
        ????throw?new?Error('');
        ??}?catch?(e)?{
        ????return?fn1();
        ??}?finally?{
        ????return?fn2();
        ??}
        }

        console.log(getData());

        //?打印順序:?'fn1',?'fn2',?2

        在?try/catch?代碼塊中,如果碰到?return xxyyzz;?關鍵詞,那么?xxyyzz?會先執(zhí)行并把值放在臨時變量里,接著去執(zhí)行?finally?代碼塊的內容后再返回該臨時變量。如果?finally?中也有?return aabbcc?,那么會立即返回新的數(shù)據(jù)?aabbcc?。

        25

        是否存在這樣的變量?x?,使得它等于多個數(shù)字?

        const?x?=?{
        ??value:?0,
        ??toString()?{
        ????return?++this.value;
        ??}
        }

        x?==?1?&&?x?==?2?&&?x?==?3;????//?true

        通過隱式轉換,這樣不是什么難的事情。

        26

        clearTimeout?和?clearInterval?可以互換~~~~使用嗎

        var?timeout?=?setTimeout(()?=>?console.log(1),?1000);
        var?interval?=?setInterval(()?=>?console.log(2),?800);

        clearInterval(timeout);
        clearTimeout(interval);

        答案是:YES?。大部分瀏覽器都支持互相清理定時器,但是建議使用對應的清理函數(shù)。

        27

        下面的打印順序是?

        setTimeout(()?=>?{
        ??console.log(1);
        },?0);

        new?Promise((resolve)?=>?{
        ??console.log(2);
        ??resolve();
        }).then(()?=>?console.log(3));

        function?callMe()?{
        ??console.log(4);
        }

        (async?()?=>?{
        ??await?callMe();
        ??console.log(5);
        })();

        答案是:2, 4, 3, 5, 1

        主線任務:2,4

        微任務:3,5
        宏任務:1

        28

        null?是?object?類型,但又不是繼承于?Object?,它更像一個歷史遺留的?bug?。鑒于太多人在用這個特性,修復它反而會導致成千上萬的程序出錯。

        typeof?null?===?'object';??????????????//?true
        Object.prototype.toString.call(null);??//?[object?Null]
        null?instanceof?Object;????????????????//?false

        腦袋空了,想到再加。。。

        1. 感謝閱讀,歡迎分享給身邊的朋友,



        版權聲明

        本文來源:“原罪”,版權歸原作者所有,如有侵權請后臺聯(lián)系小編刪除。



        資源分享


        謝謝您的支持,需要任何資源,只需要在公眾號后臺回復對應數(shù)字即可:

        01:dotnet
        02:java
        03:android
        04:C++
        05:qt
        06:react

        沒有的資源或資源鏈接失效,請給我留言或加我微信。
        另:大部分資源可在我的網(wǎng)站搜索哦:https://dotnet9.com



        瀏覽 37
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            女人15一17毛片 | 国产丝袜一区视频在线观看 | 黑人插逼视频 | 99久久精品手机毛片免费 | 日本操逼的 | 嫩草影院久久 | 黑人做爱精品一区二区 | 国产操逼电影大全 | 日韩电影中文字幕 | 日本一二三区视频 |