24가지 자바스크립트 면접 질문

小云云
풀어 주다: 2020-07-30 16:24:54
원래의
4639명이 탐색했습니다.

24가지 자바스크립트 면접 질문

요즘에는 프로그래머 업계를 선택하는 사람들이 많아지고 있습니다. 학업을 마치면 취업을 하러 나가기 때문에 면접을 볼 때 매우 긴장하고 소심한 분들도 있을 것입니다. 프로그래머 인터뷰 중에는 면접관 외에도 자신의 능력을 평가하기 위해 특별히 고안된 인터뷰 질문도 있으므로 이 기사에서는 JavaScript 인터뷰 질문 24개에 대해 설명합니다. 이제 여러분, 이점이 있으니 서둘러 획득하세요!

관련 기사 추천: 2020년 js 인터뷰 질문의 가장 완벽한 모음(최신)

1 bar가 잠재적인 객체인지 확인하려면 typeof bar === "object"를 사용하세요. 단점? 이 단점을 피하는 방법은 무엇입니까?

let obj = {};let arr = [];console.log(typeof obj === 'object');  //trueconsole.log(typeof arr === 'object');  //trueconsole.log(typeof null === 'object');  //tru
로그인 후 복사

위 출력 결과에서 typeof bar === "object"는 bar가 객체인지 정확하게 판단할 수 없음을 알 수 있습니다. Object.prototype.toString.call(bar) === "[object Object]":

let obj = {};let arr = [];console.log(Object.prototype.toString.call(obj));
  //[object Object]console.log(Object.prototype.toString.call(arr));  //[object Array]console.log(Object.prototype.toString.call(null));  //[object Null]
로그인 후 복사

2를 사용하면 이 단점을 피할 수 있습니다. 다음 코드는 콘솔에 잘못된 내용을 출력합니까? 왜?

(function(){
  var a = b = 3;})();console.log("a defined? " + (typeof a !== 'undefined'));   console.log("b defined? " + (typeof b !== 'undefined'));
로그인 후 복사

이것은 변수 범위와 관련이 있습니다. 출력은 다음과 같이 변경됩니다.

console.log(b); //3console,log(typeof a); //undefined
로그인 후 복사

자체 실행 함수에서 변수 할당을 분해합니다.

b = 3; 전역 변수 , a 는 자체 실행 함수의 지역 변수입니다.

3. 다음 코드는 콘솔에 잘못된 내용을 출력합니까? 왜?

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        (function() {
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        }());
    }};myObject.func();
로그인 후 복사

첫 번째와 두 번째 출력은 판단하기 어렵지 않습니다. ES6 이전에는 JavaScript에 함수 범위만 있었기 때문에 func의 IIFE에는 자체적인 범위가 있었고 외부 범위에서 self에 액세스할 수 있었습니다. 액세스 가능한 범위에서 이것이 정의되지 않았고 네 번째 출력이 bar이기 때문에 오류가 발생합니다. 클로저에 대해 알고 있다면 해결하기 쉽습니다:

(function(test) {console.log("inner func:  this.foo = " + test.foo);  //'bar'console.log("inner func:  self.foo = " + self.foo);}(self));
로그인 후 복사

클로저에 익숙하지 않다면 여기를 클릭하세요: 범위 체인의 클로저에 대해 이야기하기

4 함수 블록에 JavaScript 코드를 포함시키는 것에 대해 흥미로운 점이 있습니다. 모직물? 왜 이런 일을 하는가?

즉, 즉시 호출 함수 표현식을 사용하는 이유는 무엇입니까?

IIFE에는 두 가지 일반적인 사용 시나리오가 있습니다. 하나는 정기적으로 루프에서 데이터 항목을 출력하는 것과 유사하고, 다른 하나는 JQuery/Node 플러그인 및 모듈 개발과 유사합니다.

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);  
    }, 1000);}
로그인 후 복사

위의 출력은 생각한 대로 0, 1, 2, 3, 4가 아니지만 모든 출력은 5이므로 IIFE가 유용할 수 있습니다.

for(var i = 0; i < 5; i++) {
    (function(i) {
      setTimeout(function() {
        console.log(i);  
      }, 1000);
    })(i)}
로그인 후 복사

JQuery/Node 플러그인 및 모듈 개발에서, 가변 오염을 피하기 위해 IIFE도 중요합니다.

(function($) { 
        //代码
 } )(jQuery);
로그인 후 복사

5. 엄격 모드('엄격 사용')에서 JavaScript를 개발하면 어떤 이점이 있나요?

Javascript 구문의 불합리하고 느슨한 측면을 제거하고 이상한 동작을 줄입니다.

코드 실행의 안전하지 않은 측면을 제거하고 코드 실행의 안전성을 보장합니다.

컴파일러 효율성을 향상하고 실행 속도를 높입니다. 향후 새로운 버전의 Javascript를 위해.

6. 다음 두 함수의 반환 값은 동일합니까? 왜?

function foo1(){
  return {
      bar: "hello"
  };}function foo2(){
  return
  {
      bar: "hello"
  };}
로그인 후 복사

프로그래밍 언어에서는 기본적으로 문장을 구분하는 데 세미콜론(;)을 사용하는데, 이는 코드의 가독성과 깔끔함을 높일 수 있습니다. JS에서는 각 문이 독립적인 줄을 차지하는 경우 일반적으로 문 사이에 세미콜론(;)을 생략할 수 있습니다. JS 파서는 정상적으로 컴파일 가능한지 여부에 따라 세미콜론을 자동으로 채울지 여부를 결정합니다.

var test = 1 + 2console.log(test);  //3
로그인 후 복사

위에서 경우에 따라 순서대로 코드가 올바르게 구문 분석되면 세미콜론이 자동으로 채워지지 않습니다. 그러나 return, break 및 continue와 같은 문 뒤에 개행 문자가 오면 파서가 자동으로 세미콜론(;)을 채웁니다. , 따라서 위의 두 번째 함수는 다음과 같습니다.

function foo2(){return;{bar: "hello"};}
로그인 후 복사

두 번째 함수는 정의되지 않은 값을 반환합니다.

7. 센마는 NaN형인가요? 값이 NaN과 같은지 테스트하는 방법은 무엇입니까?

NaN은 JavaScript의 특수 숫자 값인 Not a Number의 약어입니다. isNaN(param)을 사용하여 값이 NaN인지 확인할 수 있습니다.
console.log(isNaN(NaN)); //trueconsole.log(isNaN(23));
 //falseconsole.log(isNaN(&#39;ds&#39;)); //trueconsole.log(isNaN(&#39;32131sdasd&#39;));
  //trueconsole.log(NaN === NaN); //falseconsole.log(NaN === undefined); 
  //falseconsole.log(undefined === undefined); //falseconsole.log(typeof NaN);
   //numberconsole.log(Object.prototype.toString.call(NaN)); 
   //[object Number]ES6 中,isNaN() 成为了 Number 的静态方法:Number.isNaN().
로그인 후 복사

8. 설명 다음 코드의 출력을 살펴보세요

console.log(0.1 + 0.2);   //0.30000000000000004console.log(0.1 + 0.2 == 0.3);  //false
로그인 후 복사

JavaScript의 숫자 유형은 부동 소수점입니다. 이는 분수를 정확하게 나타낼 수 있는 이진 표현입니다. 1/2, 1/8, 1/1024와 같이 각 부동 소수점 숫자는 64비트를 차지합니다. 그러나 이진 부동 소수점 숫자 표현은 0.1과 같은 단순한 숫자를 정확하게 표현할 수 없으며 반올림 오류가 발생합니다.

바이너리 시스템으로 인해 JavaScript는 1/10, 1/2 등과 같은 분수를 제한된 방식으로 표현할 수 없습니다. 이진수로 1/10(0.1)은 0.00110011001100110011... 로 표현되는데 0011은 무한히 반복되는데 이는 반올림 오류로 인해 발생하므로 0.1 + 0.2 등의 연산의 경우 피연산자를 먼저 이진수로 변환한 후, 재계산:

0.1 => 0.0001 1001 1001 1001… (무한 루프)

0.2 => 0.0011 0011 0011 0011… (무한 루프)

배정밀도 부동 소수점 숫자의 소수 부분은 최대 52비트를 지원합니다. 두 개는 동일합니다. 더하면 0.01001100110011001100110011001100...이라는 문자열이 나옵니다. 부동 소수점 수의 소수 자릿수 제한으로 인해 잘린 이진수입니다. 이때 이를 십진수로 변환하면 0.30000000000000004가 됩니다.

对于保证浮点数计算的正确性,有两种常见方式。

一是先升幂再降幂:

function add(num1, num2){
  let r1, r2, m;
  r1 = (&#39;&#39;+num1).split(&#39;.&#39;)[1].length;
  r2 = (&#39;&#39;+num2).split(&#39;.&#39;)[1].length;
  m = Math.pow(10,Math.max(r1,r2));
  return (num1 * m + num2 * m) / m;}console.log(add(0.1,0.2));   //0.3console.log(add(0.15,0.2256)); //0.3756
로그인 후 복사

二是是使用内置的 toPrecision() 和 toFixed() 方法,注意,方法的返回值字符串。

function add(x, y) {
    return x.toPrecision() + y.toPrecision()}console.log(add(0.1,0.2));  //"0.10.2"
로그인 후 복사

9、实现函数 isInteger(x) 来判断 x 是否是整数

可以将 x 转换成10进制,判断和本身是不是相等即可:

function isInteger(x) { return parseInt(x, 10) === x; }
로그인 후 복사

ES6 对数值进行了扩展,提供了静态方法 isInteger() 来判断参数是否是整数:

Number.isInteger(25) // trueNumber.isInteger(25.0) // trueNumber.isInteger(25.1) // falseNumber.isInteger("15") // falseNumber.isInteger(true) // false

JavaScript能够准确表示的整数范围在 -2^53 到 2^53 之间(不含两个端点),超过这个范围,无法精确表示这个值。ES6 引入了Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限,并提供了 Number.isSafeInteger() 来判断整数是否是安全型整数。

10、在下面的代码中,数字 1-4 会以什么顺序输出?为什么会这样输出?

(function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 1000); 
    setTimeout(function(){console.log(3)}, 0); 
    console.log(4);})();
로그인 후 복사

这个就不多解释了,主要是 JavaScript 的定时机制和时间循环,不要忘了,JavaScript 是单线程的。

11、写一个少于 80 字符的函数,判断一个字符串是不是回文字符串

function isPalindrome(str) {
    str = str.replace(/\W/g, &#39;&#39;).toLowerCase();
    return (str == str.split(&#39;&#39;).reverse().join(&#39;&#39;));}
로그인 후 복사

12、写一个按照下面方式调用都能正常工作的 sum 方法

console.log(sum(2,3));   // Outputs 5console.log(sum(2)(3));  // Outputs 5
로그인 후 복사

针对这个题,可以判断参数个数来实现:

function sum() {var fir = arguments[0];if(arguments.length === 2) {return arguments[0] + arguments[1]} else {return function(sec) {return fir + sec;}}}
로그인 후 복사

13、下面的代码会输出什么?为什么?

var arr1 = "john".split(&#39;&#39;); j o h nvar arr2 = arr1.reverse(); n h o jvar arr3 = "jones".split(&#39;&#39;); j o n e s
arr2.push(arr3);console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
로그인 후 복사

会输出什么呢?你运行下就知道了,可能会在你的意料之外。

MDN 上对于 reverse() 的描述是酱紫的:

>DescriptionThe reverse method transposes the elements of the calling array object in place, mutating the array, and returning a reference to the array.>reverse()
로그인 후 복사

会改变数组本身,并返回原数组的引用。>slice 的用法请参考:slice

14、下面的代码会输出什么?为什么?

console.log(1 +  "2" + "2");console.log(1 +  +"2" + "2");console.log(1 +  -"1" + "2");console.log(+"1" +  "1" + "2");console.log( "A" - "B" + "2");console.log( "A" - "B" + 2);
로그인 후 복사

输出什么,自己去运行吧,需要注意三个点:

多个数字和数字字符串混合运算时,跟操作数的位置有关

console.log(2 + 1 + &#39;3&#39;); / /‘33’console.log(&#39;3&#39; + 2 + 1); //&#39;321&#39;
로그인 후 복사

数字字符串之前存在数字中的正负号(+/-)时,会被转换成数字

console.log(typeof &#39;3&#39;);   // stringconsole.log(typeof +&#39;3&#39;);  //number
로그인 후 복사

同样,可以在数字前添加 '',将数字转为字符串

console.log(typeof 3);   // numberconsole.log(typeof (&#39;&#39;+3));  //string
로그인 후 복사

对于运算结果不能转换成数字的,将返回 NaN

console.log(&#39;a&#39; * &#39;sd&#39;);   //NaNconsole.log(&#39;A&#39; - &#39;B&#39;);  // NaN
로그인 후 복사

这张图是运算转换的规则

24가지 자바스크립트 면접 질문

15、如果 list 很大,下面的这段递归代码会造成堆栈溢出。如果在不改变递归模式的前提下修善这段代码?

var list = readHugeList();var nextListItem = function() {
    var item = list.pop();
    if (item) {
        // process the list item...
        nextListItem();
    }};
로그인 후 복사

原文上的解决方式是加个定时器:

var list = readHugeList();var nextListItem = function() {
    var item = list.pop();
    if (item) {
        // process the list item...
        setTimeout( nextListItem, 0);
    }};
로그인 후 복사

解决方式的原理请参考第10题。

16、什么是闭包?举例说明

可以参考此篇:从作用域链谈闭包(去看看)

17、下面的代码会输出什么?为啥?

for (var i = 0; i < 5; i++) {
  setTimeout(function() { console.log(i); }, i * 1000 );}
로그인 후 복사

请往前面翻,参考第4题,解决方式已经在上面了

18、解释下列代码的输出

console.log("0 || 1 = "+(0 || 1));console.log("1 || 2 = "+(1 || 2));console.log("0 && 1 = "+(0 && 1));console.log("1 && 2 = "+(1 && 2));
로그인 후 복사

逻辑与和逻辑或运算符会返回一个值,并且二者都是短路运算符:

逻辑与返回第一个是 false 的操作数 或者 最后一个是 true的操作数

console.log(1 && 2 && 0);  //0console.log(1 && 0 && 1);  //0console.log(1 && 2 && 3);  //3
로그인 후 복사

如果某个操作数为 false,则该操作数之后的操作数都不会被计算

逻辑或返回第一个是 true 的操作数 或者 最后一个是 false的操作数

console.log(1 || 2 || 0); //1console.log(0 || 2 || 1); //2console.log(0 || 0 || false); //false
로그인 후 복사

如果某个操作数为 true,则该操作数之后的操作数都不会被计算

如果逻辑与和逻辑或作混合运算,则逻辑与的优先级高:

console.log(1 && 2 || 0); //2console.log(0 || 2 && 1); //1console.log(0 && 2 || 1); //1
로그인 후 복사

在 JavaScript,常见的 false 值:

0, &#39;0&#39;, +0, -0, false, &#39;&#39;,null,undefined,null,NaN
로그인 후 복사

要注意空数组([])和空对象({}):

console.log([] == false) //trueconsole.log({} == false) //falseconsole.log(Boolean([])) //trueconsole.log(Boolean({})) //true
로그인 후 복사

所以在 if 中,[] 和 {} 都表现为 true:

24가지 자바스크립트 면접 질문

19、解释下面代码的输出

console.log(false == '0')console.log(false === '0')请参考前面第14题运算符转换规则的图。

20、解释下面代码的输出

var a={},
    b={key:&#39;b&#39;},
    c={key:&#39;c&#39;};a[b]=123;a[c]=456;console.log(a[b]);
로그인 후 복사

输出是 456,参考原文的解释:

The reason for this is as follows: When setting an object property, JavaScript will implicitly stringify the parameter value. In this case, since b and c are both objects, they will both be converted to "[object Object]". As a result, a[b] anda[c] are both equivalent to a["[object Object]"] and can be used interchangeably. Therefore, setting or referencing a[c] is precisely the same as setting or referencing a[b].

21、解释下面代码的输出

console.log((function f(n){return ((n > 1) ? n * f(n-1) : n)})(10));
로그인 후 복사

结果是10的阶乘。这是一个递归调用,为了简化,我初始化 n=5,则调用链和返回链如下:

24가지 자바스크립트 면접 질문

22、解释下面代码的输出

(function(x) {
    return (function(y) {
        console.log(x);
    })(2)})(1);
로그인 후 복사

输出1,闭包能够访问外部作用域的变量或参数。

23、解释下面代码的输出,并修复存在的问题

var hero = {    _name: &#39;John Doe&#39;,    getSecretIdentity: function (){        return this._name;    }};
var stoleSecretIdentity = hero.getSecretIdentity;console.log(stoleSecretIdentity());console.log(hero.getSecretIdentity());
将 getSecretIdentity 赋给 stoleSecretIdentity,等价于定义了 stoleSecretIdentity 函数:
var stoleSecretIdentity =  function (){return this._name;}
로그인 후 복사

stoleSecretIdentity 的上下文是全局环境,所以第一个输出 undefined。若要输出 John Doe,则要通过 call 、apply 和 bind 等方式改变 stoleSecretIdentity 的this 指向(hero)。

第二个是调用对象的方法,输出 John Doe。

24、给你一个 DOM 元素,创建一个能访问该元素所有子元素的函数,并且要将每个子元素传递给指定的回调函数。

函数接受两个参数:

DOM
指定的回调函数

原文利用 深度优先搜索(Depth-First-Search) 给了一个实现:

function Traverse(p_element,p_callback) {
   p_callback(p_element);
   var list = p_element.children;
   for (var i = 0; i < list.length; i++) {
       Traverse(list[i],p_callback);  // recursive call
   }}
로그인 후 복사

以上就是24个JavaScript的面试题,不管你是不是准备要出去找工作了,我相信这一套题目对大家都很有帮助。

相关推荐:

php初级面试题之简述题(一)

php初级面试题之简述题(二)

关于javascript常见面试题_javascript技巧

最让人容易出错的10道php面试题

php面试题中笔试题目的汇总

위 내용은 24가지 자바스크립트 면접 질문의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!