總結一些前端基礎的知識,有些知識可能在前端面試的時候會問到,所以做個記錄,也有助於其他人檢視,如果有什麼問題,可以指出,會積極修正。
變數型別和計算
JS中typeof的型別有哪些
console.log(typeof undefined); //undefined
console.log(typeof 123); //number
console.log(typeof '123'); //string
console.log(typeof true); //boolean
console.log(typeof [1,2,3]); //object
console.log(typeof {"id": 11}); //object
console.log(typeof null); //object
console.log(typeof console.log); //function
複製程式碼
型別轉換
- 顯式型別轉換
- Number 函式
- 數字:轉換後還是數字
- 字串:如果可以被解析為數值,則為相應的數值,如果不能,則是 NaN,如果是空字串那就是0
- 布林值:true為1,false為0
- undefined:NaN
- null:0
- object:先執行valueOf,看是否能轉換,如果不可以再執行toString,看是否可以轉換,如果不可以報錯
- String 函式
- 數字:轉換成對應的字串
- 字串:還是對應的字串
- 布林值:true為'true',false為'false'
- undefined:undefined
- null:null
- object:先執行toString,看是否能轉換,如果不可以再執行valueOf,看是否可以轉換,如果不可以報錯
- Boolean
下面這幾個是false,其他都是true- NaN
- null
- undefined
- 0
- ""
- false
- Number 函式
- 隱式型別轉換
- 四則運算
- 判斷語句
- 奇葩的型別轉換面試題
何時使用==
,何時使用===
除了obj.a == null
以外,都用===
,==
要用的時候一定要是已經定義的
obj.a == null
轉換之後其實是 obj.a == null || obj.a == undefined
JS中有哪些內建函式
Object
Array
Boolean
Number
String
Function
Date
RegExp
Error
複製程式碼
JS變數按照儲存方式有哪些型別
- 1.值型別
- 2.引用型別(節省空間,公用記憶體塊)
區別:值型別改變一個不會影響其他的,引用型別改變都改變,因為公用記憶體塊
如何理解JSON
JSON是JS的一個物件,也是一種資料格式,JSON中的兩個api如下
- 將JSON字串轉換成JSON物件
JSON.parse()
- 將JSON物件轉換成JSON字串
JSON.stringify()
使用Object.prototype.toString
獲取一個物件的型別
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(/s/); // [object RegExp]
toString.call([]); // [object Array]
//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
複製程式碼
原型和原型鏈
原型的五條規則
- 所有的引用型別都可以自定義新增屬性
- 所有的引用型別都有自己的隱式原型(proto)
- 函式都有自己的顯式原型(prototype)
- 所有的引用型別的隱式原型都指向對應建構函式的顯示原型
- 使用引用型別的某個自定義屬性時,如果沒有這個屬性,會去該引用型別的__proto__(也就是對應建構函式的prototype)中去找
如何準確判斷一個變數是陣列型別
arr instanceof Array
instanceof判斷一個引用型別是什麼引用型別,是通過__proto__(隱式原型一層一層往上找,能否找到對應建構函式的prototype)
寫一個原型鏈繼承的例子
function Element(ele) {
this.ele = document.getElementById(ele);
}
Element.prototype.html = function(val) {
var ele = this.ele;
if (val) {
ele.innerHTML = val;
return this;
} else {
return ele.innerHTML;
}
};
Element.prototype.on = function(type, fn) {
var ele = this.ele;
ele.addEventListener(type, fn);
return this;
}
var element = new Element('main');
element.html('hello').on('click', function() {
alert('handleClick');
});
複製程式碼
描述new一個物件的過程
- 建立一個新物件
- this指向這個新物件
- 執行程式碼給this賦值
- return this
function Foo(name) {
this.name = name;
// return this; // 本身會執行這一步
}
var f = new Foo('shiyanping');
複製程式碼
作用域及閉包
變數提升
以下兩種情況會進行提升:
- 變數定義
- 函式說明
this幾種不同的使用場景
- 在建構函式中使用(建構函式本身)
- 作為物件屬性時使用(呼叫屬性的物件)
- 作為普通函式時使用(window)
- call,apply,bind(執行的第一個引數)
var a = {
name: 'A',
fun: function() {
console.log(this.name);
}
};
a.fun(); //this === a
a.fun.call({ name: 'B' }); //this === { name: 'B' }
var fun1 = a.fun;
fun1(); //this === window
複製程式碼
建立10個a標籤,點選每個彈出對應的序號
var i;
for (i = 0; i < 10; i++) {
(function(i) {
// 函式作用域
var a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click', function(e) {
e.preventDefault();
alert(i);
});
document.body.appendChild(a);
})(i);
}
複製程式碼
如何理解作用域
- 自由變數
- 作用域鏈,及自由變數的查詢,找不到逐級向上找
- 閉包的兩個場景
- 函式作為變數傳遞
- 函式作為返回值
實際開發中閉包的應用
// 判斷一個數字是否出現過
function isFirst() {
var _list = [];
return function(id) {
if (_list.indexOf(id) >= 0) {
return false;
} else {
_list.push(id);
return true;
}
};
}
var first = isFirst();
first(10);
first(10);
first(20);
複製程式碼
單執行緒和非同步
同步和非同步的區別,分別列舉一個同步和非同步的例子
同步會阻塞程式碼,但是非同步不會 alert是同步 setTimeout是非同步
關於setTimeout的筆試題
console.log(1);
setTimeout(function() {
console.log(2);
}, 0);
console.log(3);
setTimeout(function() {
console.log(4);
}, 1000);
console.log(5);
// 輸出結果:1,3,5,2,4
複製程式碼
前端使用非同步的場景
- 定時任務:setTimeout,setInterval
- 網路請求:ajax請求,動態img載入
- 事件繫結
需要等待的情況下都需要非同步,因為不會像同步一樣阻塞
日期和Math
知識點:
日期
console.log(Date.now()); // 獲取當前毫秒數
var dt = new Date(); // 獲取當前時間
console.log(dt.getTime()); // 當前時間的毫秒數
console.log(dt.getFullYear()); // 年
console.log(dt.getMonth()+1); // 月(0-11)
console.log(dt.getDate()); // 日(0-31)
console.log(dt.getHours()); // 時(0-23)
console.log(dt.getMinutes()); // 分(0-59)
console.log(dt.getSeconds()); // 秒(0-59)
複製程式碼
Math
Math.random()
- 返回 0 ~ 1 之間的隨機數Math.abs(x)
- 返回數的絕對值Math.ceil(x)
- 向上取整Math.floor(x)
- 向下取整
常用的陣列api
- forEach(遍歷所有元素)
var arr = ['a', 'b', 'c', 'd'];
arr.forEach(function (item, index) {
console.log(item + ',' + index);
})
複製程式碼
- map(對陣列進行重新組裝,生成新的陣列)
// map,生成新陣列,不改變原來陣列的格式
var arr = ['a', 'b', 'c', 'd'];
var result = arr.map(function (item, index) {
return index + '/' + item;
})
console.log(result);
複製程式碼
- sort(對陣列進行排序)
// sort, 會改變原來陣列
var arr = [1, 23, 3, 4];
var result = arr.sort(function (a, b) {
// 從小到大排序
return a - b;
// 從大到小排序
// return b - a;
})
console.log(result);
複製程式碼
- filter(過濾符合條件的元素)
var arr = [1, 2, 3, 4];
var result = arr.filter(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result);
複製程式碼
- every(判斷所有元素是否都符合要求)
var arr = [1, 2, 3, 4];
var result = arr.every(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result); // false
複製程式碼
- some(判斷是否有至少一個元素符合條件)
var arr = [1, 2, 3, 4];
var result = arr.some(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result); // true
複製程式碼
- join(根據條件對陣列組合成字串)
var arr = [1, 2, 3, 4];
var result = arr.join(',');
console.log(result);
複製程式碼
- reverse(將陣列反轉)
var arr = [1, 2, 3, 4];
var result = arr.reverse();
console.log(result);
複製程式碼
常用的物件api
- for in
- hasOwnProperty(檢查屬性是不是物件自有的,排除從原型鏈找到的屬性)
var obj = {
x: 10,
y: 20,
z: 30
}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key + ':' + obj[key]);
}
}
複製程式碼
問題:
獲取當前日期
function formatDate(dt) {
if (!dt) {
dt = new Date();
}
var year = dt.getFullYear();
var month = dt.getMonth() + 1;
var date = dt.getDate();
if (month < 10) {
month = '0' + month;
}
if (date < 10) {
date = '0' + date;
}
return year + '-' + month + '-' + date;
}
var nowDate = new Date();
var formatDate = formatDate(nowDate);
console.log(formatDate);
複製程式碼
獲取隨機數,要求長度一致的字串格式
function randomStr(len) {
var random = Math.random();
random = random + '0000000000'; // 防止自動生成的數字不滿足長度報錯並且強制轉換成字串
return random.substr(0, len)
}
console.log(randomStr(20));
複製程式碼
寫一個能遍歷物件和陣列的通用forEach函式
function forEach(obj, fn) {
if (obj instanceof Array) {
obj.forEach(function (item, index) {
fn(index, item);
})
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
fn(key, obj[key]);
}
}
}
}
var arr = [1, 2, 3, 4];
forEach(arr, function (index, item) {
console.log(index + ',' + item);
});
var obj = {
x: 10,
y: 20
};
forEach(obj, function (index, item) {
console.log(index + ',' + item);
});
複製程式碼
後續還在持續更新中