---
# System prepended metadata

title: 前端工程師 javascript 面試

---

# 前端工程師 javascript 面試問題紀錄

近期開始面試多家公司，這邊整理出筆試或面試上遇到的問題，希望可以幫助到需要的人還有我自己也能複習。
**[參考網址做額外補充!](https://www.explainthis.io/zh-hant/swe-questions/frontend)**

### 下列有哪些屬性是傳址(call by reference)特性?
> Array、Number、Function、Object、String、Undefined

**ans:**
|| Array、Function、Object ||

說明:
js的資料類型(data type)分為兩大類，一種是原始型別(primitive type)和物件(object)。
- 原始型別有:
	- Number
	- String
	- Null
	- BigInt
	- Boolean
	- **Undefined**
	- Symbol

- Object:
	- 除了原始型態以外的型態，如 array、function、object、map...

簡單說明結論，object型態的類型基本上就是傳址的特性，在呼叫使用時，會是使用到該物件上的地址，如果在物件屬性中重新賦值的話會有參考改變的特性，需要注意。

---
### 下列輸出結果為?

1. console.log(undefined === undefined);
2. console.log(NaN == NaN);
3. console.log(isNaN('NIHOW'));
4. console.log({} === '[object Object]');
5. console.log(0.1+0.2 == 0.3);
6. console.log(typeof[1,2,3]== 'array');
7. console.log(null == undefined);
8. console.log(null === undefined);

**ans:**
|| 1. true
 2. false
 3. true 
 4. false 
 5. false
 6. false
 7. true 
 8. false||

---
### 請解釋變數和函式宣告提升(Hoisting)? 下列結果為?
```javascript!
function foo(param) {
	console.log(num);
	console.log(param);
	console.log(arguments[1]);
	say();
	
	var num = 1;
	function say(){
		console.log(2+num);
	}
	
	return 33;
}

foo('4','5');
```

**ans:**
1. 變數提升: 當使用`var`宣告時，此變數會被提升到其所在函式或作用域的頂部，表示可以再宣告前就使用該變數，但是他的值會是`undefined`。
2. 函數提升: js中的function也會如此，因此也能在函數宣告之前就調用了。
3. || undefined '4' '5' NaN ||

答案說明:要注意看宣告前後，我在寫題目時寫出的答案是錯的，因為我沒有注意到`say()`函式執行下` var num` 的位置，所以答錯了QQ。

---
### 請問下列 A、B、C、D、E、F 各自打印了幾次?
```javascript!
for(let i = 0; i <= 10; i++) {
	console.log('A');
	for(let j = 0; j < 10; j++) {
		console.log('B');
		
		if(i == 3 && j == 6) {
			console.log('C');
		}
		
		if(i==j) {
			console.log('D');
		}
		if(i&&j) {
			consolog.log('E');
		}
	}	
}
```

**ans:**
||A: 11 次(0~10共11次打印)
B: 110 次(第一層陣列11次 x 第二層陣列10次(<=10) = 110)
C: 1 次
D: 10 次(i跟j為0~9時才會打印，所以是10次)
E: 90 次(這個判斷相等於判斷i跟j是否都不是0也就是說判斷是否存在)||

```javascript!
let j = 0;
while(j <= 100) {
	console.log('F')
}
```
**ans:**
|| 無限次 因為沒有設置終止條件，可以在log下面增加 j++; 就不會無限打印了 ||

---
### 1綜合判斷 :
```javascript!
var obj ={};
console.log(delete obj.p);
```
**ans:**
|| true ||
### 2綜合判斷 :

```javascript!
const a = {}
const b = {key: 'b'}
const c = {key: 'c'}
a[b] = 123
a[c] = 456
console.log(a[b])
```
**ans:**
|| 456 ||

### 3綜合判斷 :
```javascript!
let obj = {name:'jimmy', age:18};
let obj1 = obj;
obj.name = 'chimmy'
console.log(obj1)
obj1 = {}
obj.age = 22
console.log(obj1)
```
**ans:**
|| {name: 'chimmy', age: 18}
{}
||

說明:
||注意重新賦值的位置，當obj1重新賦值後他就不再和obj1為相同位"址"了，所以會是空的。||
### 4綜合判斷:
```javascript!
var f = function() {
	console.log('1');
}
function f(){
	console.log('2');
}
f()
```
**ans:**
|| 1 ||

說明: 因為提升的關係，`var f` 跟 `function f` 都被提升到最頂部，接著執行賦值的 `function() {console.log('1')}`，因為函數聲明(就是"=")會覆蓋函式，所以當在使用`f()`其實就只會觸發到聲明中的log '1'。

### 5綜合判斷:
```javascript!
function Student(name) {
	this.name = name;
	console.log(this);
}
var result = new Student('jimmy');
```
**ans:**
|| Student {name: 'jimmy'} ||

### 6綜合判斷:
```javascript!
var name = 'jimmy';
var student = {
	name: 'chimmy',
	doSth: function() {
		console.log(this.name)
	},
	doSth2: function() {
		var arrowDoSth = () => {
			console.log(this.name);
		}
		arrowDoSth();
	},
	doSth3: () => {
		console.log(this.name);
	}
}
student.doSth()
student.doSth2()
student.doSth3()
```
**ans:**
|| 'chimmy' 'chimmy' 'jimmy'||

說明:
箭頭函式不會創造自己的`this`，所以看到箭頭函式要往上看他繼承的外部函式的this對象，外部函式只到誰，箭頭函式的this就會是誰，所以doSth2中的this其實也指向student本身。

### 1請寫出下列程式碼執行結果:
```javascript!
var name = 'my name is window'
var obj = {
	name: 'my name is obj',
	fn: function () {
		setTimeout( () => {
			console.log(this.name)
		}, 1000)
	}
}
obj.fn()
```
|| my name is obj ||

說明:
因為閉包的特性，函式在使用時會保留上下文所以就算外面有個全域變數，箭頭函式下的this還是會指回原本的obj當中。

### 2請寫出下列程式碼執行結果:
```javascript!
const obj = {a:'one', b:'two', a: 'three'}
console.log(obj)
```
||SybtaxError 重複屬性名||

### 請倒敘印出Array中的內容，並且使用Array.prototype中的reduce完成
```javascript!
const numbers = [0,1,2,3,4,5,6,7]
function revertNumbers(params){
	const ans = []
	params.reduce(function(total, el) {
		ans.unshift(el)
		return total // 返回已累積的陣列
	},[])// 空陣列是提供reduce方法做初始的累積紀錄
	// 如果要回傳字串就用ans.join('')
	return ans
}
revertNumbers(numbers)
```