프론트 엔드 개발 학교 모집 면접 질문 정렬 [1] - JavaScript

프론트 엔드 개발 학교 모집 면접 질문 정렬 [1] - JavaScript

앞에 작성:

인터뷰 질문은 모두 정리되어 GitHub에 공유되었습니다.
주소: https://github.com/shadowings-zy/front-end-school-recruitment-question

1. 자바스크립트의 기초

Q: js의 기본 데이터 유형을 소개합니다.

기본 유형(값 유형): 문자열, 숫자, 부울, Null, 정의되지 않음, 기호, BigInt.

숫자의 종류에는 정수와 부동소수점이 있으며, 정수의 정밀도는 2^53이고 부동소수점 값의 최고 정밀도는 소수점 이하 17자리입니다.
또한 NAN은 디지털 유형에 속하며 숫자가 아닌 것을 나타냅니다. 즉, 1/0=NAN, NAN/1=NAN입니다.
무한대는 더하기 또는 빼기 기호로 범위를 초과하는 숫자를 나타냅니다.

정의되지 않음: 변수가 선언되었지만 값을 포함하지 않음을 나타냅니다.
null: 변수가 비어 있음을 나타냅니다.

참조 유형: 객체, 배열, 함수(사실 모두 객체이고 모두 참조입니다).

데이터 캡슐화 개체: 개체, 배열, 부울, 숫자, 문자열 기타
개체: 함수, 인수, 수학, 날짜, RegExp, 오류

기본 유형은 스택 메모리에 저장되고 참조 유형은 힙 메모리에 저장됩니다.

Q: js에서 객체의 유형을 판단하는 방법은 무엇입니까?

typeof를 사용하여 javascript 기본 개체의 유형을 결정합니다.

typeof 'John' // 返回 string
typeof 3.14 // 返回 number
typeof NaN // 返回 number
typeof false // 返回 boolean
typeof [1, 2, 3, 4] // 返回 object
typeof {
    
     name: 'John', age: 34 } // 返回 object
typeof new Date() // 返回 object
typeof function () {
    
    } // 返回 function
typeof myCar // 返回 undefined (如果 myCar 没有声明)
typeof null // 返回 object

생성자를 사용하면 생성자의 유형을 반환할 수 있으며 생성자의 이름에 따라 유형을 판단할 수 있습니다.

"John".constructor // 返回函数 String() {[native code]}
(3.14).constructor // 返回函数 Number() {[native code]}
false.constructor // 返回函数 Boolean() {[native code]}
[1,2,3,4].constructor // 返回函数 Array() {[native code]}
{
    
    name:'John', age:34}.constructor // 返回函数 Object() {[native code]}
new Date().constructor // 返回函数 Date() {[native code]}
function () {
    
    }.constructor // 返回函数 Function() {[native code]}

instanceof를 사용하여 다음과 같은 참조 유형을 감지합니다.

console.log(person instanceof Object) // 变量 person 是 Object 吗?
console.log(colors instanceof Array) // 变量 colors 是 Array 吗?
console.log(pattern instanceof RegExp) // 变量 pattern 是 RegExp 吗?

Q: js의 프로토타입 체인을 어떻게 이해합니까?

프로토타입 체인

객체가 있는 한 프로토타입이 있고 프로토타입도 객체이기 때문에 객체가 정의되고 그 프로토타입을 찾을 수 있는 등 일련의 객체가 형성될 수 있으며 이는 구조를 프로토타입 체인이라고 합니다.

각 객체는 프로토타입(prototype)이라는 속성을 초기화하는데, 객체의 속성에 접근할 때 그 속성이 객체에 존재하지 않으면 프로토타입으로 가서 속성을 찾고, 나만의 프로토타입이 있어서 이렇게 계속 찾게 되는데, 우리가 흔히 프로토타입 체인이라고 부르는 개념입니다.

참고: instance.constructor.prototype = instance.proto

Q: js에서 function.call과 function.apply의 차이점은 무엇입니까?

function.apply(thisObj, [argArray])
function.call(thisObj, arg1, arg2,, argN);

적용: 객체의 메소드를 호출하여 현재 객체를 다른 객체로 교체합니다. 예: B.apply(A, arguments) 즉, A 객체가 B 함수를 적용합니다. 즉, B 컨텍스트를 초기 컨텍스트에서 A 컨텍스트로 변경합니다.

호출: 객체의 메서드를 호출하여 현재 객체를 다른 객체로 바꿉니다. 예: B.call(A, args1, args2) 즉, A 개체가 B 개체의 메서드를 호출합니다.

Q: js의 범위를 어떻게 이해합니까?

전역 범위: 가장 바깥쪽 계층에 기록된 개체 또는 내부 계층에 기록되었지만 var로 선언되지 않은 변수, 범위는 전역입니다. 예를 들면 다음과 같습니다.

var outerVar = "outer";
function fn() {
    
    
  innerVar = “inner”;
  console.log(outerVar);
}
fn(); //result:outer
console.log(innerVar); //result:inner

함수 범위: 함수 내에서 var를 사용하여 선언된 변수를 작성합니다. 예를 들면 다음과 같습니다.

function fn() {
    
    
  var innerVar = 'inner'
}
console.log(innerVar) // ReferenceError: innerVar is not defined

범위 체인: 내부 함수는 외부 함수의 변수에 대한 액세스를 연결할 수 있습니다. 예를 들면 다음과 같습니다.

name = 'aaa'

function b() {
    
    
  var name = 'bbb'

  function c() {
    
    
    var name = 'ccc'
    console.log(name) //ccc
  }

  function d() {
    
    
    console.log(name) //bbb
  }
  c()
  d()
}
b()
console.log(name) //aaa

Q: js에서 클로저란 무엇입니까?

클로저는 js의 범위 기능을 활용하고 반환 값이 함수인 함수를 사용하여 내부 함수가 외부 함수의 변수에 액세스할 수 있도록 합니다. 외부 함수를 호출할 때 반환 값 함수를 호출하여 외부 함수의 변수를 수정할 수 있습니다.

클로저는 다른 함수의 범위에 있는 변수에 액세스할 수 있는 함수입니다.
기능:
1. 전역 변수의 개체를 줄일 수 있어 과거에 전역 변수가 너무 커서 유지 관리가 어려운 것을 방지합니다..
2. 지속적인 수정을 방지합니다.
3. 이 변수의 값이 항상 메모리에 유지되도록 함수 내부의 변수를 읽습니다.

예를 들어:

const add = function () {
    
    
  let counter = 0
  return function () {
    
    
    counter++
    return counter
  }
}

const x = add()
console.log(x()) // 计数器为 1
console.log(x()) // 计数器为 2
console.log(x()) // 计数器为 3

2. 자바스크립트 흐름 제어

Q: js에서 Promise를 사용하는 방법에 대해 알려주십시오.

Promise 객체는 외부 세계의 영향 을 받지
않는 비동기 작업을 나타내며 세 가지 상태를 가집니다
.

Promise 객체는 다음과 같은 네 가지 메서드를 제공합니다.
then // 비동기 작업이 완료되면 메서드를 호출합니다.
catch // 비동기 작업이 실패하면 메서드를 호출
합니다. all // 모든 함수 작업이 완료된 후 race 메서드를 호출합니다.
// 메서드를 호출합니다. 첫 번째 작업이 완료되거나 실패한 후

예를 들어:

function read(time) {
    
    
  console.log('正在阅读')
  let p = new Promise(function (resolve, reject) {
    
    
    setTimeout(function () {
    
    
      console.log('阅读完毕')
      time = time + 1
      resolve(time)
    }, 2000)
  })
  return p
}

function write(time) {
    
    
  console.log('正在写作')
  let p = new Promise(function (resolve, reject) {
    
    
    setTimeout(function () {
    
    
      console.log('写作完毕')
      time = time + 1
      resolve(time)
    }, 2000)
  })
  return p
}

function rest(time) {
    
    
  console.log('正在休息')
  let p = new Promise(function (resolve, reject) {
    
    
    setTimeout(function () {
    
    
      console.log('休息完毕')
      time = time + 1
      resolve(time) //把promise的状态设置为resolved,成功
    }, 2000)
  })
  return p
}

function badDream(time) {
    
    
  console.log('正在做梦')
  let p = new Promise(function (resolve, reject) {
    
    
    setTimeout(function () {
    
    
      console.log('做了噩梦')
      time = time + 1
      reject(time) //把promise的状态设置为rejected,失败
    }, 2000)
  })
  return p
}

read(0)
  .then(function (data) {
    
    
    return write(data)
  })
  .then(function (data) {
    
    
    return badDream(data)
  })
  .then(function (data) {
    
    
    return rest(data)
  })
  .then(function (data) {
    
    
    console.log(data)
  })
  .catch(function (data) {
    
    
    //处理失败的方法
    console.log('第' + data + '步出错')
  })

const p1 = new Promise(function (resolve, reject) {
    
    
  setTimeout(function () {
    
    
    console.log('p1完成')
    resolve(11)
  }, 1000)
})

const p2 = new Promise(function (resolve, reject) {
    
    
  setTimeout(function () {
    
    
    console.log('p2完成')
    resolve(22)
  }, 2000)
})

const p3 = new Promise(function (resolve, reject) {
    
    
  setTimeout(function () {
    
    
    console.log('p3完成')
    resolve(33)
  }, 3000)
})

//all,所有函数都执行结束后,回调方法
Promise.all([p1, p2, p3]).then(function (data) {
    
    
  console.log('全部完成', data)
})

//race,第一个函数执行结束后,回调方法
Promise.race([write(1), rest(2)]).then(function (results) {
    
    
  console.log('准备工作完毕:')
  console.log(results)
})

Q: js에서 async 및 await의 사용법에 대해 알려주세요. Promise와의 차이점은?

async는 함수가 비동기 함수임을 나타내기 위해 함수 앞에 키워드로 배치됩니다.
비동기는 비동기를 의미하므로 비동기 함수는 함수 실행이 다음 코드의 실행을 차단하지 않음을 의미합니다.
async는 console.log(timeout())와 같은 Promise 객체를 반환하고 resolve가 hello world를 반환하고 거부가 예외를 throw하면 Promise 객체를 가져옵니다.
그러나 이것이 요점이 아니라 async의 가장 큰 장점은 내부에서 await를 사용할 수 있어 then Promise 체인을 보다 간결하게 처리할 수 있다는 것입니다.
async에 await가 없으면 실제로 반환 값을 반환하는 resolve를 가진 Promise 객체와 동일합니다.

await 표현식은 현재 비동기 함수의 실행을 일시 중단하고 Promise가 처리되기를 기다립니다. Promise가 정상적으로 이행되면 콜백의 resolve 함수 매개 변수가 await 표현식의 값으로 사용되며 async 함수가 계속 실행됩니다. Promise가 예외(거부됨)를 처리하는 경우 await 표현식은 Promise의 예외 이유를 발생시킵니다. 또한 await 연산자 뒤의 표현식 값이 Promise가 아니면 값 자체가 반환됩니다.

async와 await의 조합은 Promise의 then chain을 보다 직관적으로 처리할 수 있습니다.

예:
Promise 작성 방법:

doSomething()
  .then(function (res) {
    
    
    return doNext(res)
  })
  .then(function (nextRes) {
    
    
    return doFinalThing(nextRes)
  })
  .then(function (finalResult) {
    
    
    console.log('Got the final result: ' + finalResult)
  })
  .catch(failureCallback)

async/await 작성 방법:

try {
    
    
  const result = await doSomething()
  const nextRes = await doNext(result)
  const finalResult = await doFinalThing(newResult)
  console.log('Got the final result: ' + finalResult)
} catch (error) {
    
    
  failureCallback(error)
}

3. JavaScript 공통 데이터 구조

Q: 일반적으로 사용되는 Array API에 대해 알려주십시오.

Array API의 초점은 API가 무엇인지 아는 것이 아니라 사용할 수 있다는 것입니다.

push(a)           // 末尾添加,返回数组长度
unshift(a)	      // 首位添加,返回数组长度
shift()	          // 删除第一个元素,并返回删除的元素
pop()	            // 删除最后一个元素,并返回删除的元素
join(a)	          // 把数组中的所有元素放到一个字符串中,分隔符为a
concat(a, b)	    // 将b连接到a后面
sort()	          // 数组排序
reverse()	        // 数组倒序
isArray(a)	      // a是否为数组
slice(a, b)	      // 根据输入的开始点和末尾点,截取出新的数组(包括前不包括后)
splice(a, b, c)	  // 从a位置开始,删除b长度的数组,插入c

indexOf(a)	      // 从前向后寻找值等于a的项,返回index
lastIndexOf(a)	  // 从后向前寻找等于a的项,返回index

every(function(item, index, array))	      // 对数组每一项运行一次某函数,若函数每一项都为true,返回true
some(function(item, index, array))	      // 对数组每一项运行一次某函数,若函数某一项为true,返回true
filter(function(item, index, array))	    // 对数组每一项运行一次某函数,返回返回值为true的项的数组
map(function(item, index, array))	        // 对数组每一项运行一次某函数,返回返回值的数组
forEach(function(item, index, array))	    // 对数组每一项运行一次某函数,无返回值
reduce(function(prev, cur, index, array)) //接收四个参数:前一个值、当前值、项的索引和数组对象,这个函数的任意返回值会作为第一个参数传给下一项。

Q: 배열/객체 통과의 for in과 for의 차이점은 무엇입니까?

배열의 경우: for in은 배열 인덱스 값(아래 첨자)을 출력하고 of는 배열 요소를 출력합니다.
개체의 경우: for in은 개체 키 값을 출력하고 of는 개체 값 값을 출력합니다.

Q: 배열 병합을 구현하는 코드는 무엇입니까?

const arr = [1, 3, [3, 4, [5, 6]]]

// 第一种方案:用现成api,不兼容低版本的浏览器
const arr1 = arr.flat(Infinity)

// 第二种方案:原生循环递归实现
function flat2(arr) {
    
    
  const result = []
  arr.forEach((item) => {
    
    
    if (Array.isArray(item)) {
    
    
      result.push(...flat(item))
    } else {
    
    
      result.push(item)
    }
  })
  return result
}
const arr2 = flat2(arr)

// 第三种方案:使用解构和递归实现
function flat3(arr) {
    
    
  const result = [].concat(...arr.map((x) => (Array.isArray(x) ? flat(x) : x)))
  return result
}
const arr3 = flat3(arr)

Q: 딥카피 객체를 구현하기 위한 코드는 무엇인가요?

// 对象中如果均为基本类型
JSON.parse(JSON.stringify(obj))

// 对象中如果既有基本类型,还有Array和Object
function deepCopy(data) {
    
    
  let output
  if (data === null || !(typeof data === 'object')) {
    
    
    output = data
  } else {
    
    
    output = data.constructor.name === 'Array' ? [] : {
    
    }
    for (let key in data) {
    
    
      output[key] = deepCopy(data[key])
    }
  }
  return output
}

Q: "test"와 new String("test")의 차이점은 무엇이며 {}와 new Object()의 차이점은 무엇입니까?

"test"는 문자열 유형의 상수이고 new String()은 문자열 객체를 생성합니다.

const obj1 = new String('abc') // 类型为object
const obj2 = 'abc' // 类型为string

obj1 == obj2 // true
obj1 === obj2 // false

{}와 new Object() 모두 자체적으로 객체를 생성하고 객체에 대한 참조를 반환합니다.

const obj1 = new Object('abc') // 类型为object
const obj2 = {
    
    } // 类型为obejct

obj1 == obj2 // false
obj1 === obj2 // false

4. DOM/BOM API

Q: addEventListener는 어떻게 사용하나요? onxxx와 다른 점은 무엇입니까?

onxxx는 모든 브라우저에서 지원하는 DOM0의 표준이며 이벤트 이름을 DOM 개체에 직접 등록합니다.
예를 들어:

document.getElementById('click').onclick = function (event) {
    
    
  console.log(event.target)
}

addEventListener는 DOM2의 표준으로 IE8 이상의 브라우저에서 지원되며 캡처 단계, 대상 단계 및 버블링 단계의 세 단계로 나뉩니다.
각 이벤트는 먼저 루트에서 대상 요소로 전달된 다음 다시 루트로 전달됩니다.

Q: 이벤트 프록시는 무엇을 의미합니까?

이벤트 프록시는 여러 요소(예: li)에 이벤트를 추가하기 위해 요소의 상위 요소에 이벤트를 추가하는 것을 의미하며, 이벤트가 발생하면 이벤트 대상을 캡처하여 대상을 판단하고 해당 이벤트를 실행합니다 e.target.

Q: js를 사용하여 쿠키에 액세스하는 방법은 무엇입니까? js로 쿠키에 대한 액세스를 금지하려면 어떻게 해야 합니까?

쿠키를 보려면 document.cookie를 사용하십시오. 쿠키 저장 형식은 key=value;key=value;형식의 문자열입니다.

헤더에 HttpOnly를 설정하면 js가 쿠키에 액세스하지 못하도록 할 수 있습니다.

Q: js를 사용하여 브라우저의 가시 영역을 계산하는 방법은 무엇입니까?

// 获取浏览器窗口的可视区域的宽度
const width = document.documentElement.clientWidth || document.body.clientWidth

// 获取浏览器窗口的可视区域的高度
const height = document.documentElement.clientHeight || document.body.clientHeight

Supongo que te gusta

Origin blog.csdn.net/u011748319/article/details/119898891
Recomendado
Clasificación