十道前端面試題(1)

  1. call apply bind的區別
  2. 數組去重
  3. http狀態碼
  4. css彈性佈局
  5. position屬性有哪些值,分別有什麼含義
  6. constlet的區別,可以改變const定義對象某個屬性嗎
  7. this的理解, 如何改變this的指向
  8. letvar的區別,let的產生背景
  9. var的變量提升底層原理是什麼
  10. 箭頭函數,箭頭函數的特點

點擊瞭解更多ES6知識 >>


1. call apply bind的區別?

相同點: 都可以改變函數調用的this指向
不同點:

  1. callapply的用法幾乎相同,唯一不同就是參數不同。call只能一個一個參數傳入,apply參數是一個數組。
  2. bind的傳參方式和call相同,但是改變調用函數的指向並返回一個新的函數,之後再調用這個函數時候this就指向bind綁定的第一個參數

call語法

  1. fun.call(thisArg,arg1,arg2,...)
  2. thisArgfun函數運行時指定的this值(在非嚴格模式下,指定爲nullundefined時會自動指向全局對象)
  3. arg1,arg2,...是指定的參數列表

apply語法

  1. fun.apply(thisArg, [argsArray])
  2. thisArgfun函數運行時指定的this值(在非嚴格模式下,指定爲nullundefined時會自動指向全局對象)
  3. argsArray是一個數組或類數組對象,數組中的元素將作爲單獨的參數傳給fun函數,如果 argsArraynullundefined時表示不需要傳入任何參數。

示例:
數組沒有max方法,可以使用Math對象上的max方法

const arr = [1,2,3,4,5,6];
const max = Math.max.apply(null,arr);  // 6

bind語法

  1. fun.bind(thisArg,arg1,arg2,...)
  2. thisArg當綁定函數被調用時,該參數會作爲原函數運行時的this指向。當使用new 操作符調用綁定函數時,該參數無效。
  3. arg1, arg2, ...當綁定函數被調用時,這些參數將置於實參之前傳遞給被綁定的方法。
// 如果你某個函數綁定新的this指向並且固定先傳入幾個變量可以在綁定的時候就傳入,之後調用新函數傳入的參數都會排在之後
const obj = {}
function test(...args) {
	console.log(args);
}
const newFn = test.bind(obj, 1,2);
newFn(3,4);     // [1,2,3,4]

使用場景

  1. 當一個函數需要改變this指向時
  2. 且參數較少時可以使用call
  3. 如果參數較多,可以將參數整理到一個數組,使用apply
  4. 如果想生成一個新函數長期綁定某個對象時,可以使用bind

2. 數組去重

  • 方法一:
    這是個沒有什麼技術含量的方法(使用了ES6 Set數據結構)!
	let arr = [1,1,1,1,2,3,4,5,5,6];
	arr = [...new Set(arr)];       // [1,2,3,4,5,6]
  • 方法二:
    for循環嵌套for循環
function unique(arr){
	for(let i = 0; i<arr.length; i++) {
		for(let j = i+1; j < arr.length; j++) {
			if(arr[i] === arr[j]){
				arr.splice(j,1);   // 去除重複的這個
				j--;
			}
		}
	}
	return arr;
}
  • 方法三
    使用indexOf方法,或數組的includes方法
    function unique(arr) {
    	let arr1 = [];
    	for(let i=0; i<arr.length; i++) {
    		if(arr1.indexOf(arr[i]) === -1) {  // !arr1.includes(arr[i])
    			arr1.push(arr[i]);      // 如果arr1中不存在該元素則push進arr1
    		}	
    	}
    	return arr1;
    }
    
  • 方法四
    利用sort排序後,相鄰元素進行對比
function unique(arr) {
	arr.sort( (a,b) => a-b);
	for(let i=0; i< arr.length-1; i++){
		if(arr[i] === arr[i+1]) {
			arr.splice(i+1,1);
		}
	}
	return arr;
}


當然不只這幾種方法。。歡迎評論補充


3. http狀態碼(點擊查看 >>)


4. CSS彈性佈局(點擊查看 >>)


5.position屬性有哪些值,分別有什麼含義

position屬性規定元素的定位類型

屬性值 描述
absolute 生成絕對定位的元素。相對於除了static定位以外的第一個父元素定位
fixed 生成絕對定位的元素,相對於瀏覽器窗口定位
relative 生成相對定位元素,相對於自己原來的位置定位
static 默認值。沒有定位,元素出現在正常流中(忽略 top, bottom, left, right 或者 z-index 聲明)
inherit 繼承父元素position的值

6. const和let的區別,可以改變const定義對象某個屬性嗎

  1. constlet都只在聲明的塊級作用域內有效
  2. let聲明的變量可以改變,值和類型都可以改變,且可以先聲明,後賦值。
  3. const聲明一個常量,值不可以改變,且一旦聲明就得賦值。
  4. 對於const聲明一個引用類型的變量(如:數組,對象),變量名不指向數據,而是指向引用類型數據所在的地址(即變量保存的是指向這個引用類型的指針),因此可以改變const定義對象的某個屬性值。

7. this的理解, 如何改變this的指向

  1. this值函數運行時所在的環境(即調用的對象)
  2. 可以理解爲誰調用函數,this就指向誰
  3. 可以上述序號1的call,apply,bind方法改變this指向

8. let和var的區別,let的產生背景?

  1. let聲明變量會形成塊級作用域,var不能
  2. let聲明變量只能先聲明後使用(暫時性死區),即let不存在變量提升

示例:

{
	let a =1;
}
console.log(a);   // a is not defined

9. var的變量提升底層原理是什麼

JS引擎的工作方式:

  1. 先解析代碼,獲取所有聲明的變量
  2. 然後再運行

也就是分爲預處理和執行兩個階段

變量提升的定義: 所有的變量聲明語句會被提升到聲明變量所在作用域的頭部
定義與賦值分離

示例:

console.log(a);    // 報錯 a is not defined
console.log(b);   // undefined
var b = 1;

上面的代碼相當於:

var b;
console.log(b);    // undefined
b = 1;

10. 箭頭函數,箭頭函數的特點

  1. 相比普通函數更簡潔的語法
  2. 本身沒有this,捕獲其所在上下文(作用域)的this值,作爲自己的 this 值
  3. 不能使用new
  4. 不綁定arguments,用rest參數...解決
  5. 使用call()apply()調用
  6. 箭頭函數沒有原型屬性
  7. 不能簡單返回對象字面量
  8. 箭頭函數不能當做Generator函數,不能使用yield關鍵字
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章