JS基礎知識點及常考面試題(1)
- 原始型別有哪幾種?null是物件嘛?
- 物件型別和原始型別的不同之處?函式引數是物件會發生什麼問題?
- typeof是否能正確判斷型別?instanceof 能正確判斷物件的原理是什麼?
- 型別轉換有哪些?
- 如何正確判斷this? 箭頭函式的this 是什麼?
1.原始型別有哪幾種?null是物件嘛?
原始型別有boolean, null, undefined, string, number, symbol
null不算是物件,雖然type of null為object, 這是JS存在的一個悠久的BUG.
注: 原始型別儲存的儲存的都是值,是沒有函式可以呼叫的,
undefined.toString()會報錯, 但是 '1'.toString()可以使用,是因為'1'已經被強制轉換成String型別(物件型別)
2.物件型別和原始型別的不同之處?函式引數是物件會發生什麼問題?
原始型別儲存的是值,物件型別儲存的是地址(指標).
函式引數是物件的時候,是傳遞的物件指標的副本。
function test(person) {
person.age = 26
person = {
name: 'yyy',
age: 30
}
return person
}
const p1 = {
name: 'yck',
age: 25
}
const p2 = test(p1)
// p1 作為副本傳入test函式,但副本改變,與p1無關
console.log(p1) // -> { name: 'yck', age: 25 }
console.log(p2) // -> person = { name: 'yyy', age: 30 }
複製程式碼
3.typeof 是否能正確判斷型別?instanceof 能正確判斷物件的原理是什麼?
typeof 對於原始型別來說,除了null 都可以顯示正確都型別。
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
複製程式碼
typeof 對物件來說, 除了函式都會顯示Object, 所以不能正確都判斷型別
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
複製程式碼
instanceof 能正確判斷物件都原理是通過原型鏈來判斷,但直接判斷原始型別是不行。
注:
如果需要instanceof 可以支援判斷原始型別,使用Symbol內建屬性hasInstance
class PrimitiveString {
static [Symbol.hasInstance](x) {
return typeof x === 'string'
}
}
console.log('hello world' instanceof PrimitiveString) // true
複製程式碼
還可以用toString() + call方法來判斷
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全域性物件 global 的引用
複製程式碼
function typeJudge(data) {
// 先通過toString()判斷,
return Object.prototype.toString.call(data).replace(/^\[object/, '').replace(/\]$/, '').toLocaleLowerCase()
}
複製程式碼
4.型別轉換有哪些?
轉boolean
在條件判斷時, 除了undefined, null, false, NaN, "", 0, -0, 其他所有的值和所有物件轉為true.
轉string [] 或者 [''] => '', 關鍵字(new, function) => 拋錯, 物件 => '[object Object]'.
除了陣列,關鍵字,物件以外,都直接外層加引號就可以了
String([]) // ''
String(['']) // ''
String(null) // 'null'
String(NaN) // 'NaN'
複製程式碼
轉number
[] 或者 [''] => 0, 關鍵字(new, function) => 拋錯, null => 0, undefined => NaN
物件轉原始型別 優先順序 Symbol.toPrimitive > valueOf() > toString()
四則運算子
- 運算中其中一方為字串,那麼就會把另一方也轉換為字串
- 如果一方不是字串或者數字,那麼會將它轉換為數字或者字串
5.如何正確判斷this? 箭頭函式的this 是什麼?
- 對於直接呼叫 foo 來說,不管 foo 函式被放在了什麼地方,this 一定是 window
- 對於 obj.foo() 來說,我們只需要記住,誰呼叫了函式
- 對於 new 的方式來說,this 被永遠繫結在了 c 上面,不會被任何方式改變 this
- 箭頭函式中的 this 只取決包裹箭頭函式的第一個普通函式的 this。
注:new > bind這些函式 > obj.foo() > foo() 直接呼叫
bind函式的this取決於第一次呼叫