前端開發必會的JS硬知識

本文簡介

  • 前端三座大山是HTML、CSS、JS,而Javascript是前端最核心的部分。
  • 通常來講,完整的JavaScript=ECMAScript+DOM+BOM
  • 讓咱們進入JS的深刻學習旅程吧

js數據類型

數據類型有哪些?有什麼特色?

  • 最新的 ECMAScript 標準定義了8種數據類型:
  • 七種基本數據類型 「值類型」:
    1. 布爾值(Boolean),有2個值分別是:true 和 false.
    2. null , 一個代表 null 值的特殊關鍵字。JavaScript 是大小寫敏感的,所以 null 與 Null、NULL或變體徹底不一樣。
    3. undefined ,和 null 同樣是一個特殊的關鍵字,undefined 表示變量未賦值時的屬性。
    4. 數字(Number),整數或浮點數,例如:42 或者 3.14159。
    5. 任意精度的整數 (BigInt) ,能夠安全地存儲和操做大整數,甚至能夠超過數字的安全整數限制。
    6. 字符串(String),字符串是一串表示文本值的字符序列,例如:"Howdy" 。
    7. 表明(Symbol) ( 在 ECMAScript 6 中新添加的類型)。一種實例是惟一且不可改變的數據類型。 補充:

      typeof Symbol() === 'symbol'; // true Symbol('key') !== Symbol('key'); // true Symbol('key') === Symbol('key'); // false前端

  • 一種引用類型「對象(Object)」 包括:Array Function Date

特色:java

  1. 值類型的賦值,實際就是值的拷貝
  2. 引用類型的賦值,實際就是地址的拷貝

熱身訓練

請說出如下代碼打印的結果es6

if (1 == true) 
    console.log(1)
if (1 === true)
     console.log(2)
if ([]) 
    console.log(3)
if ([] == []) 
    console.log(4)
if ([] === [])
    console.log(5)
if (undefined == null)
    console.log(6)
if ('' == null) 
    console.log(7)
if (NaN == NaN) 
    console.log(8)
複製代碼
  • 解析:undefined == null ?二者都是無效值。js規範規定,在比較相等性以前,undefined和null不能轉化成其餘類型的值,且undefined和null是相等的。
  • 解析:undefined === null ?二者不是同一數據類型。== 比較的是值, === 比較的是值和數據類型

    typeof undefined // undefined typeof null // object數組

  • 解析:'' == null ?
    • null: 該值聲明的是一個空對象,沒有指向任何的內存空間。
    • '':該字符串聲明的是一個對象實例,該實例是一個長度爲0的字符串
    • 拓展:str = '' 放在棧內存 str = String('') 指向堆內存
  • 解析:NaN == NaN ?
    • NaN屬性(not a number)是表明非數字值的特殊值。
    • 任何值和NaN作比較都是false。
    • 任何數和NaN作運算,結果都爲NaN。
    • NaN不和任何值相等,包括它自己

    console.log(isNaN(NaN)) //true console.log(isNaN(10)) //false console.log(isNaN('20')) //false 將'20'轉爲數字類型20 console.log(isNaN('abc')) //true console.log(isNaN(true)) //false 將true轉爲1瀏覽器

淺拷貝與深拷貝

  • 淺拷貝:增長了一個指針指向已存在的內存地址
  • 深拷貝:增長了一個指針而且申請了一個新的內存,使這個增長的指針指向這個新的內存
  • 舉個栗子🌰

    const a = [1,2,3]; const b = a; b[0] = 5;
    a = ? // [5, 2, 3]緩存

  1. 這是淺拷貝,由於a和b指向同一塊內存地址。當a賦值給b時, 只是將a的數據指針賦值給b,並無開闢屬於b的內存空間。
  2. 若是是深拷貝,應該爲b開闢獨立的內存空間,而且將a的內容拷貝過來。二者互不影響。

深拷貝的實現

let obj = {
    name: 'kk',
    bf: ['a', 1],
    a() {
        console.log('d')
    },
    offer: null
}
function deepClone(origin, target={}) {
    const toStr = Object.prototype.toString,
         arrStr = "[object Array]"
    for(let prop in origin) {
        if(origin.hasOwnProperty(prop)) {
            if(origin[prop] !== null && typeof origin[prop] === 'object') {
                target[prop] = toStr.call(origin[prop]) === arrStr ? [] : {}
                deepClone(origin[prop], target[prop])
            } else {
                target[prop] = origin[prop]
            }
        }
    }
    return target
}

let ans = deepClone(obj)
ans.offer = 'xxx'
console.log(ans, obj)
複製代碼

typeof 和 instanceof 的區別

  1. typeof用於判斷變量的類型
  • 數值類型 typeof 2 返回 number
  • 字符串類型 typeof 'ac' 返回 string
  • 布爾類型 typeof true 返回 boolean
  • 對象、數組、null, 返回 object
  • 函數 typeof eval 、typeof Date 返回 function
  • 不存在的變量、函數或者undefined, 返回 undefined
  1. instanceof判斷某個對象是否被某個函數構造

區別:安全

  • typeof採用引用類型存儲值時出現問題,不管引用的是什麼類型的對象,都會返回object
  • es引入java的instaceof解決問題
  • instanceof與typeof類似,用於識別正在處理的對象類型。
  • 不一樣的是,instaceof要求開發者明確地確認對象爲某特定類型

== 和 === 有什麼區別?

  • ==只判斷值是否相等
  • ===判斷值是否相等,類型是否相同

數組、對象那些事

判斷數組類型的方法

  1. Array.isArray(arr) => true
  2. Object.prototype.toString.call(arr) => "[object Array]"
  3. arr instanceof Array => true
  4. arr.constructor == Array => true **instanceof和constructor,必須在當前頁面聲明。若是是父頁面引入iframe,也判斷不出來**

函數中的 arguments 是數組嗎?

  • arguments是類數組,原型(proto)指向的是Object;而真正數組指向Array。
  • document.getElementByTagName 返回的也是類數組,原型指向HTMLCollection.

如何將函數中的arguments轉化爲真正的數組?

  • Array.from(arguments)
  • [].slice.call(arguments)
  • 擴展運算符(當數組或者對象只有一層的時候,意思是不存在數組嵌套對象,或者嵌套數組這種狀況,拷貝是深拷貝。除了第一層是深拷貝,其它層都是淺拷貝) [...arguments]
  • [].concat.apply([],arguments)
  • Array.of(...arguments)
  • Array(...arguments)

Array的forEach等用法

  1. forEach:遍歷數組(for)
  2. map: 返回一個數組,不改變原數組的內容
  3. every:每一個元素都符合條件,就返回true

    arr.every((val, index, array)=>val=='a')markdown

  4. some: 只要有一個元素符合條件,就返回true

    arr.some((val, index, array)=>val=='a')閉包

  5. filter: 返回一個數組,裏面都是符合條件的元素。

    arr.filter((val, index, array)=>val=='a')app

  6. reduce: 返回一個數 可進行遞歸、疊加、階乘,從左到右 (reduceRight 從右到左)

    arr.reduce((prev,cur,index,arr)=>{ // 加法 // return prev+cur // 階乘 // return Math.pow(prev,cur) return prev**cur })

如何遍歷一個對象?

  • for(let prop in obj)
  • object.keys(obj); object.values(obj)
  • object.getOwnPropertyNames(obj)

閉包與做用域

閉包就是可以讀取其餘函數內部變量的函數

請實現一個「有緩存功能」的加法

let add = (()=>{
    let sum = 0
    return  n=>sum += n
})()
console.log(add(5), add(6), add(1))
複製代碼

什麼是做用域?細分爲哪些做用域?

瀏覽器給js的生存環境叫做用域。

  • 函數做用域
    • 在函數調用的時候,會建立函數做用域。調用完會摧毀
    • 每一次調用函數都會建立一個函數做用域,而且相互獨立
    • 函數做用域能夠訪問全局做用域的變量,全局做用域不能夠訪問函數做用域的變量
    • 函數內訪問變量,會從自身函數做用域內找,找不到就往上一級做用域找,直到找到全局做用域。若是仍是找不到,就返回ReferenceError
    • 在函數做用域內要訪問全局變量,可使用window
  • 全局做用域
  • 塊級做用域(下一欄目)

let、const、var的區別?

  1. 何時提出?
  • var是es5提出的,let、const是es6提出的
  1. 變量提高
  • var可以進行變量提高,let、const不能夠
  1. 暫時性死區(TDZ)
  • 在塊級做用域內,let、const具備暫時死區,一進入做用域內,變量就已經存在,可是在變量聲明前不能被訪問或者調用,不然會報錯 ReferenceError
  1. 重複聲明
  • var能夠重複聲明
  • let、const不能夠
  1. 是否存在塊級做用域
  • var不存在(一、內部變量可能會覆蓋外部變量二、用於計數的循環變量泄露爲全局變量)
  • let、const存在
  1. 聲明的變量可否被修改
  • var和let能夠 const不能夠,一旦聲明必須當即初始化

更多精彩內容,請關注公衆號。

前端交流羣(羣裏大佬如雲,會常常分享優秀的文章,前端路上,結伴同行~)

相關文章
相關標籤/搜索