搜尋
首頁web前端js教程JavaScript容易被坑的問題

JavaScript容易被坑的問題

Jun 28, 2020 am 09:50 AM
javascript前端

前言

總括: 這是筆者平時累積的一些覺得比較有趣或比較有難度的JavaScript題目理解和心得,會維持長期更新。

人生莫作婦人身,百年苦樂由他人。

正文

1.setTimeout和setInterval深入理解

#在setTimeout和setInterval深入理解這篇部落格筆者曾做過總結,我們知道JavaScript試單線程的產物,兩個函數就是利用了插入程式碼的方式實作了偽異步,和AJAX的原理其實是一樣的。下面來看下這個範例:

console.log("1");
setTimeout(function(){        
    console.log("3")
},0);    console.log("2");

結果:控制台依序輸出1,2,3;

function fn() {
    setTimeout(function(){alert('can you see me?');},1000);
    while(true) {}
}

你覺得這段程式碼的執行結果是什麼呢?答案是,alert永遠不會出現。
    這是為什麼呢?因為,while這段程式碼沒有執行完,所以插入在後面的程式碼便永遠不會執行。
綜上所述,其實JS終歸是單線程產物。無論如何「異步」都不可能突破單線程這個障礙。所以許多的「非同步呼叫」(包括Ajax)事實上也只是「偽異步」而已。只要理解了這麼一個概念,或許要理解setTimeout和setInterval也就不難了。

2. 閉包初探小題

在JavaScript閉包初探這篇部落格裡面進行了初步探討,有幾個小題個人覺得還是比較有意思的:

  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());//The Window
   var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };  
  alert(object.getNameFunc()());//My Object
function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?

//問:三行a,b,c的輸出分別是什麼?

這是一個非常典型的JS閉包問題。其中嵌套了三層fun函數,搞清楚每層fun的函數是那個fun函數特別重要。

//答案:
//a: undefined,0,0,0
//b: undefined,0,1,2
//c : undefined,0,1,1

3. Array/map,Number/parseInt

["1", "2", "3"].map(parseInt)//求输出结果复制代码

  首先, map接受兩個參數, 一個回呼函數callback, 一個回呼函數的this值
其中回呼函數接受三個參數currentValue, index, arrary;而題目中, map只傳入了回調函數--parseInt.其次, parseInt 只接受兩個兩個參數string, radix(基數). radix的合法區間是2-36. 0或是預設是10.所以本題即問

parseInt('1', 0);parseInt('2', 1);parseInt('3', 2);复制代码

後兩者參數不合法.所以答案是:[1, NaN, NaN];

4. 0.1 0.2!=0.3和9999999999999999 == 10000000000000000;

根據語言規範,JavaScript 採用「IEEE 754 標準定義的雙精度64位元格式」(#根據語言規範,JavaScript 採用「IEEE 754 標準定義的雙精度 64-presion" format IEEE 754 values")表示數字。據此我們能得到一個有趣的結論,和其他程式語言(如C 和Java)不同,JavaScript 不區分整數值和浮點數值,所有數字在JavaScript 中均以浮點數值表示,所以在進行數字運算的時候要特別注意。精確度遺失看看下面的例子:

0.1 + 0.2 = 0.30000000000000004复制代码

在具體實作時,整數值通常被視為32位元整數變量,在個別實作(如某些瀏覽器)中也以32位元整數變數的形式進行存儲,直到它被用於執行某些32位元整數不支援的操作,這是為了便於進行位元操作。大整數精度在2的53次方以內是不會丟失的,也就是說瀏覽器能精確計算Math.pow(2,53)以內所有的數,小數精度,當十進制小數的二進位表示的有限數字不超過52 位元時,在JavaScript 裡也是可以精確儲存的。
解決方法:Math.round( (.1 .2)*100)/100;

5. [1

  此題會讓人誤以為是2>1&&2

1true;true1true;3true;false0true;复制代码

#答案:[true,true] 這個題的重點是對於運算子的理解,一是javascript對於不同型別數值的比較規則,詳見js比較表,javascript相等性判斷;二是對於比較運算子和賦值運算子的理解,即一個自左向右一個自右向左~

6. 瀏覽器懵逼史(1)

3.toString;3..toString;3...toString;复制代码

這個題目感覺腦洞很大啊~先說答案:error,'3',error;
但如果是

var a=3;
a.toString;复制代码

卻又合法了答案就是'3';
為啥呢?
因為在JS中1.1,1.,.1都是合法數字啊!那麼在解析3.toString的時候到底是這是個數字呢,還是方法呼叫呢?瀏覽器就懵逼了唄,只能拋出一個error,所以說感覺此題就是在戲耍瀏覽器......

7. 聲明提升

var name = 'World!';
(function () {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

答案是什麼呢...筆者第一次做的時候傻傻的覺得是Hello,world...實則不然,正確答案是:Goodbye Jack;
為什麼呢,聲明提升...上述代碼相當於下面的程式碼:

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

8. 坑爹史(1)

var a = [0];
if ([0]) {
  console.log(a == true);
} else {
  console.log("wut");
}

读者们你们觉得此题答案是什么呢?true?因为[0]被看做Boolean是被认为是true,理所当然的推出来[0]==true,控制台输出true...看似没错,然而并不是这样滴~[0]这个玩意儿在单独使用的时候是被认为是true的,但用作比较的时候它是false...所以正确答案是false;不信的话,F12控制台输出[0]==false;看是不是true......

###9. 坑爹史(2)

1 + - + + + - + 1

这题应该是等同于:(倒着看)

1 + (a)  => 2
a = - (b) => 1
b = + (c) => -1
c = + (d) => -1
d = + (e) => -1
e = + (f) => -1
f = - (g) => -1
g = + 1   => 1

答案是2

10. 坑爹史(3)

function sidEffecting(ary) {
  ary[0] = ary[2];
}
function bar(a,b,c) {
  c = 10
  sidEffecting(arguments);  return a + b + c;
}
bar(1,1,1)

此题涉及ES6语法,实在坑的不行...arguments
首先 The arguments object is an Array-like object corresponding to the arguments passed to a function.也就是说 arguments 是一个 object, c 就是 arguments2, 所以对于 c 的修改就是对 arguments2 的修改.
所以答案是 21.
然而!!!!!!
当函数参数涉及到 any rest parameters, any default parameters or any destructured parameters 的时候, 这个 arguments 就不在是一个 mapped arguments object 了.....请看:

function sidEffecting(ary) {
  ary[0] = ary[2];
}
function bar(a,b,c=3) {
  c = 10
  sidEffecting(arguments);  return a + b + c;
}
bar(1,1,1)

答案是12...
请读者细细体会!!

11. 坑爹史(4)

[,,,].join(", ")
[,,,] => [undefined × 3]

因为javascript 在定义数组的时候允许最后一个元素后跟一个,, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦)
答案: ", , "

12. 浏览器懵逼史(2)

var a = {class: "Animal", name: 'Fido'};
a.class

这个题比较流氓.. 因为是浏览器相关, class是个保留字(现在是个关键字了);Fuck!
所以答案不重要, 重要的是自己在取属性名称的时候尽量避免保留字. 如果使用的话请加引号 a['class']

13.一道容易被人轻视的面试题

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

14.闭包小题

for(var i = 0; i <h3 id="函数的隐式转换">15. 函数的隐式转换</h3><pre class="brush:php;toolbar:false">function fn() {
    return 20;
}
console.log(fn + 10); // 输出结果是多少

function fn() {
    return 20;
}

fn.toString = function() {
    return 10;
}

console.log(fn + 10);  // 输出结果是多少?

function fn() {
    return 20;
}

fn.toString = function() {
    return 10;
}

fn.valueOf = function() {
    return 5;
}

console.log(fn + 10); // 输出结果是多少?

16. 函数防抖和函数节流(ES6)

//函数节流
const throttle = (fun, delay) => {
    let last = null;
    return () => {
        const now = + new Date();
        if (now - last > delay) {
            fun();
            last = now;
        }
    }
}
//实例
const throttleExample  = throttle(() => console.log(1), 1000);
//调用
throttleExample();
throttleExample();
throttleExample();
//函数防抖
const debouce = (fun, delay) => {
    let timer = null;
    return () => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fun();
        }, delay);
    }
}
//实例
const debouceExample = debouce(() => console.log(1), 1000);
//调用
debouceExample();
debouceExample();
debouceExample();

推荐教程:《JS教程

以上是JavaScript容易被坑的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器