做者:Dmitri Pavlutin
譯者:前端小智
來源: https://dmitripavlutin.com/ja...
點贊再看,養成習慣本文
GitHub
https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。javascript
JS 的動態類型有好有壞。好的一面,沒必要指明變量的類型。很差的是,我們永遠沒法肯定變量的類型。前端
typeof
運算符能夠肯定 JS 中的6
種類型:java
typeof 10; // => 'number' typeof 'Hello'; // => 'string' typeof false; // => 'boolean' typeof { a: 1 }; // => 'object' typeof undefined; // => 'undefined' typeof Symbol(); // => 'symbol'
一樣,instanceof
運算符用於檢測構造函數的 prototype
屬性是否出如今某個實例對象的原型鏈上。git
class Cat { } const myCat = new Cat(); myCat instanceof Cat; // => true
可是typeof
和instanceof
的一些行爲可能會使人混淆。防範於未然,我們須要提早了解一些邊緣狀況。github
typeof myObject === 'object'
會告知myObject
是不是一個對象類型。舉個例子:面試
const person = { name: '前端小智' }; typeof person; // => 'object'
typeof person
是'object'
,由於person
是一個普通的 JS 對象。正則表達式
在某場景下,變量值可能須要指定爲 null
,下面是一些場景:segmentfault
null
來跳過指示配置對象null
初始化稍後要保存對象的變量null
例如,若是不存在正則表達式匹配項,則str.match(regExp)
方法返回null
:數組
const message = 'Hello'; message.match(/Hi/); // => null
這裏引出一個問題,可使用typeof 來區分有值的對象和具備 null
值的對象嗎?promise
let myObject = null; typeof myObject; // => 'object' myObject = { prop: 'Value' }; typeof myObject; // => 'object'
從上面能夠看出,typeof
對象有值的對象和具備 null
值的對象,獲得的結果都是'object'。
能夠以下面方法來檢測變量是否有對象且不是null
:
function isObject(value) { return typeof value === 'object' && value !== null; } isObject({}); // => true isObject(null); // => false
除了檢查value
是否爲object
: typeof value === 'object'
以外,還須要明確地驗證null
: value !== null
。
若是試圖檢測一個變量是否包含一個數組,常見的錯誤就是使用typeof
操做符:
const colors = ['white', 'blue', 'red']; typeof colors; // => 'object'
檢測數組的正確方法是使用Array.isArray()
:
const colors = ['white', 'blue', 'red']; const hero = { name: 'Batman' }; Array.isArray(colors); // => true Array.isArray(hero); // => false
Array.isArray(colors)
返回一個布爾值true
,表示colors
是一個數組。
JS中的undefined
是一個特殊值,表示未初始化的變量。
若是試圖訪問未初始化的變量、不存在的對象屬性,則獲取到的值爲 undefined
:
let city; let hero = { name: '前端小智', villain: false }; city; // => undefined hero.age; // => undefined
訪問未初始化的變量 city
和不存在的屬性hero.age
的結果爲undefined
。
要檢查屬性是否存在,能夠在條件中使用object[propName]
,這種遇到值爲虛值或者undefined
是不可靠的:
function getProp(object, propName, def) { // 錯誤方式 if (!object[propName]) { return def; } return object[propName]; } const hero = { name: '前端小智', villain: false }; getProp(hero, 'villain', true); // => true hero.villain; // => false
若是對象中不存在propName
,則object [propName]
的值爲undefined
。 if (!object[propName]) { return def }
保護缺乏的屬性。
hero.villain
屬性存在且值爲false
。 可是,該函數在訪問villan
值時錯誤地返回true
:getProp(hero, 'villain', true)
undefined
是一個虛值,一樣false
、0
和''
和null
。
不要使用虛值做爲類型檢查,而是要明確驗證屬性是否存在於對象中:
typeof object[propName] === 'undefined'
propName in object
object.hasOwnProperty(propName)
接着,我們來改進getProp()
函數:
function getProp(object, propName, def) { // Better if (!(propName in object)) { return def; } return object[propName]; } const hero = { name: '前端小智', villain: false }; getProp(hero, 'villain', true); // => false hero.villain; // => false
if (!(propName in object)) { ... }
條件正確肯定屬性是否存在。
我認爲最好避免使用邏輯運算符||
做爲默狀況,這個容易打斷閱讀的流程:
const hero = { name: '前端小智', villain: false }; const name = hero.name || 'Unknown'; name; // => '前端小智' hero.name; // => '前端小智' // 很差方式 const villain = hero.villain || true; villain; // => true hero.villain; // => false
hero
對象存在屬性villain
,值爲 false
,可是表達式hero.villain || true
結果爲true
。
邏輯操做符||
用做訪問屬性的默認狀況,當屬性存在且具備虛值時,該操做符沒法正確工做。
若要在屬性不存在時默認設置,更好的選擇是使用新的雙問號(??)操做符,
const hero = { name: '前端小智', villan: false }; // 好的方式 const villain = hero.villain ?? true; villain; // => false hero.villain; // => false
或使用解構賦值:
const hero = { name: '前端小智', villain: false }; // Good const { villain = true } = hero; villain; // => false hero.villain; // => false
整數,浮點數,特殊數字(例如Infinity
,NaN
)的類型均爲數字。
typeof 10; // => 'number' typeof 1.5; // => 'number' typeof NaN; // => 'number' typeof Infinity; // => 'number'
NaN
是在沒法建立數字時建立的特殊數值。NaN
是not a number
的縮寫。
在下列狀況下不能建立數字:
Number('oops'); // => NaN 5 * undefined; // => NaN Math.sqrt(-1); // => NaN NaN + 10; // => NaN
因爲NaN
,意味着對數字的操做失敗,所以對數字有效性的檢查須要額外的步驟。
下面的isValidNumber()
函數也能夠防止NaN
致使的錯誤:
function isValidNumber(value) { // Good return typeof value === 'number' && !isNaN(value); } isValidNumber(Number('Z99')); // => false isValidNumber(5 * undefined); // => false isValidNumber(undefined); // => false isValidNumber(Number('99')); // => true isValidNumber(5 + 10); // => true
除了typeof value === 'number'
以外,還多驗證!isNaN(value)
確保萬無一失。
JS 中的每一個對象都引用一個特殊的函數:對象的構造函數。
object instanceof Constructor
是用於檢查對象的構造函數的運算符:
const object = {}; object instanceof Object; // => true const array = [1, 2]; array instanceof Array; // => true const promise = new Promise(resolve => resolve('OK')); promise instanceof Promise; // => true
如今,我們定義一個父類Pet
和它的子類Cat
:
class Pet { constructor(name) { this.name; } } class Cat extends Pet { sound = 'Meow'; } const myCat = new Cat('Scratchy');
如今,嘗試肯定myCat
的實例
myCat instanceof Cat; // => true myCat instanceof Pet; // => true myCat instanceof Object; // => true
instanceof
運算符表示myCat
是Cat
,Pet
甚至Object
的實例。
instanceof
操做符經過整個原型鏈搜索對象的構造函數。要準確地檢測建立對象的構造函數,須要檢測 constructor
屬性
myCat.constructor === Cat; // => true myCat.constructor === Pet; // => false myCat.constructor === Object; // => false
只有myCat.constructor === Cat
的計算結果爲true
,表示 Cat
是 myCat
實例的構造函數。
運算符typeof
和instanceof
用於類型檢查。 它們儘管易於使用,但須要注意一些特殊狀況。
須要注意的是:typeof null
等於'object'
。 要肯定變量是否包含非null
對象,須要顯示指明null
:
typeof myObject === 'object' && myObject !== null
檢查變量是否包含數組的最佳方法是使用Array.isArray(variable)
內置函數。
由於undefined
是虛值的,因此咱們常常直接在條件句中使用它,但這種作法容易出錯。更好的選擇是使用prop in object
來驗證屬性是否存在。
使用雙問號操做系符號object.prop ?? def
或者 { prop = def } = object
來訪問可能丟失的屬性。
NaN
是一個類型爲number
的特殊值,它是由對數字的無效操做建立的。爲了確保變量有正確的數字,最好使用更詳細的驗證:!isNaN(number) && typeof number === 'number'
。
最後,請記住instanceof
經過prototype
鏈搜索實例的構造函數。若是不知道這一點,那麼若是使用父類驗證子類實例,可能會獲得錯誤的結果。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://dmitripavlutin.com/ja...
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。