Day2 - 前端高頻面試題之基礎版javascript
基本類型:null、undefined、number、string、boolean、Symbol
java
引用類型:Object、Array、Date、RegExp、Function
面試
原始類型存儲的都是值,是沒有函數能夠調用的,好比 undefined.toString()
會報TypeError的錯數組
null
用來表示還沒有存在的對象;當聲明的變量還未被初始化時,變量的默認值爲undefined
app
注意的是typeof null
返回爲object
,由於特殊值null被認爲是一個空的對象引用函數
null是一個表示"無"的對象,轉爲數值時爲0;undefined是一個表示"無"的原始值,轉爲數值時爲NaNpost
undefined == null // true
ui
從內存來看 null 和 undefined 本質的區別是什麼?this
給一個全局變量賦值爲null,至關於將這個變量的指針對象以及值清空,若是是給對象的屬性 賦值爲null,或者局部變量賦值爲null,至關於給這個屬性分配了一塊空的內存,而後值爲null, JS會回收全局變量爲null的對象。
給一個全局變量賦值爲undefined,至關於將這個對象的值清空,可是這個對象依舊存在,若是是給對象的屬性賦值 爲undefined,說明這個值爲空值
typeof 返回值:number、 boolean、string、undefined、object、function
typeof是一元運算符,返回值爲字符串,該字符串用來講明運算數的數據類型 (數組、正則、日期、對象的typeof返回值都是object)
instanceof用於判斷某個變量是不是某個對象的實例,返回值爲true或false
[] === [] //false
undefined === undefined //true
[] == [] //false
undefined == undefined //true
複製代碼
let arr = []
typeof arr === 'object'
arr instanceof Array === true
arr.constructor === Array
Array.isArray(arr) === true
Object.protoType.toString.call(arr) === "[Object Array]"
Object.protoType.toString.apply(arr) === "[Object Array]"
let num = 1
typeof num === 'number'
a.constructor === Number
Object.protoType.toString.call(num) === "[Object Number]"
Object.protoType.toString.apply(num) === "[Object Number]"
複製代碼
function foo() {
console.log(this.a)
}
var a = 1
foo()
const obj = {
a: 2,
foo: foo
}
obj.foo()
const c = new foo()
複製代碼
咱們一個個分析上面幾個場景
foo
來講,無論 foo
函數被放在了什麼地方,this
必定是 window
obj.foo()
來講,咱們只須要記住,誰調用了函數,誰就是 this
,因此在這個場景下 foo
函數中的 this
就是 obj
對象new
的方式來講,this
被永遠綁定在了 c
上面,不會被任何方式改變 this
下面看看箭頭函數中的 this
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
複製代碼
首先箭頭函數實際上是沒有 this
的,箭頭函數中的 this
只取決包裹箭頭函數的第一個普通函數的 this
。
在這個例子中,由於包裹箭頭函數的第一個普通函數是 a
,因此此時的 this
是 window
。另外對箭頭函數使用 bind
這類函數是無效的。
最後就是bind call apply
這些改變上下文的API了,對於這些函數來講,this
取決於第一個參數,若是第一個參數爲空,那麼就是 window
。
若是對一個函數進行屢次 bind
,那麼上下文會是什麼呢?
let a = {}
let fn = function () {
console.log(this)
}
fn.bind().bind(a)() // => ?
// 能夠把上述代碼轉換成另外一種形式
// fn.bind().bind(a) 等於
let fn2 = function fn1() {
return function() {
return fn.apply()
}.apply(a)
}
fn2()
// 能夠從上述代碼中發現,無論咱們給函數 bind 幾回,fn 中的 this 永遠由第一次 bind 決定,因此結果永遠是 window。
複製代碼
以上就是 this
的規則了,可是可能會發生多個規則同時出現的狀況,這時候不一樣的規則之間會根據優先級最高的來決定 this
最終指向哪裏。
首先,new
的方式優先級最高,接下來是 bind
這些函數,而後是 obj.foo()
這種調用方式,最後是 foo
這種調用方式,同時,箭頭函數的 this
一旦被綁定,就不會再被任何方式所改變。