> 웹 프론트엔드 > JS 튜토리얼 > BAT 주요 인터넷 기업의 JavaScript 프론트엔드 인터뷰 질문 요약

BAT 주요 인터넷 기업의 JavaScript 프론트엔드 인터뷰 질문 요약

不言
풀어 주다: 2018-10-25 14:15:09
앞으로
1733명이 탐색했습니다.

이 글은 주요 BAT 인터넷 기업의 JavaScript 프론트엔드 면접 질문을 요약한 것입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다. .

면접 질문의 대부분은 BAT를 인터뷰한 경험에서 나왔습니다. 더 많은 프론트엔드 분들이 함께 발전할 수 있기를 바라는 마음으로 정리해서 공유했습니다. 구직자에게 적합할 뿐만 아니라 js를 통합하고 검토하는 데에도 매우 도움이 됩니다.

그리고 그 과정에서 더 많은 질문이 수집되며, 오류나 더 나은 솔루션이 있는 경우 답변이 정확하다고 보장되지 않습니다. , 의인에게 문의해 주세요.

처음 몇 가지 질문은 매우 기본적이며, 계속 진행할 수록 더 심층적인 질문이 됩니다.

초등 자바스크립트:

#🎜 🎜 #1.자바스크립트는 어떤 언어이며, 어떤 특징이 있나요?

표준적인 답변은 없습니다.

2 JavaScript의 데이터 유형은 무엇인가요?

기본 데이터 유형: 문자열, 부울, 숫자, 정의되지 않음, Null

인용 데이터 유형: Object(Array,Date,RegExp,Function)

그럼 문제는 변수가 배열인지 확인하는 방법입니다. 데이터 유형?

  • 방법 1. 슬라이스()와 같은 "배열 특성"이 있는지 확인합니다. 방법. 이 변수에 대한 슬라이스 방법을 직접 정의할 수 있으므로 때때로 실패합니다. 새로운 메소드 Array.isArray()는 ECMA Script5에 정의되어 있으며 호환성이 보장됩니다. 호환성을 위해 가장 좋은 메소드는 다음과 같습니다:

  • if(typeof Array.isArray==="undefined")
    {
      Array.isArray = function(arg){
            return Object.prototype.toString.call(arg)==="[object Array]"
        };  
    }
    로그인 후 복사
  • # 🎜🎜#

    3. 알려진 ID로 입력 상자를 입력하세요. 이 입력 상자의 입력 값을 어떻게 얻을 수 있나요? (타사 프레임워크를 사용하지 마세요)

    document.getElementById(“ID”).value
    로그인 후 복사
  • 4. 페이지? (타사 프레임워크를 사용하지 마세요)

    var domList = document.getElementsByTagName(‘input’)
    var checkBoxList = [];
    var len = domList.length;  //缓存到局部变量
    while (len--) {  //使用while的效率会比for循环更高
      if (domList[len].type == ‘checkbox’) {
          checkBoxList.push(domList[len]);
      }
    }
    로그인 후 복사

5 알려진 ID를 가진 p의 html 콘텐츠를 xxxx로 설정합니다. 글꼴 색상을 검은색으로 설정합니다(타사 프레임워크를 사용하지 않음)

var dom = document.getElementById(“ID”);
dom.innerHTML = “xxxx”;
dom.style.color = “#000”;
로그인 후 복사

6. 함수를 실행하려면 어떻게 해야 할까요?

이벤트를 DOM에 직접 바인딩합니다.

< /p>

JS에서 onclick을 통해 바인딩: xxx.onclick = test #🎜 🎜#

    이벤트 추가를 통한 바인딩: addEventListener(xxx, 'click', test)
  • #🎜🎜 ##🎜🎜 #

  • 그렇다면 질문은 Javascript의 이벤트 흐름 모델이 무엇입니까?
  • "이벤트 버블링": 이벤트는 가장 구체적인 요소에 의해 승인되는 것으로 시작됩니다. level up 상향 전파

"이벤트 캡처": 가장 특정하지 않은 노드에서 이벤트를 먼저 수신한 후 단계별로 하향 전파합니다. , 가장 구체적으로 "DOM 이벤트 흐름": 3단계: 이벤트 캡처, 대상 단계, 이벤트 버블링 # 🎜🎜## 🎜🎜#

  • 7. Ajax와 JSON의 장점과 단점.

  • Ajax는 웹 페이지에서 비동기 데이터 상호 작용을 구현하는 데 사용되는 비동기 JavaScript 및 XML입니다.

    优点:

    • 可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量

    • 避免用户不断刷新或者跳转页面,提高用户体验

    缺点:

    • 对搜索引擎不友好(

    • 要实现ajax下的前后退功能成本较大

    • 可能造成请求数的增加

    • 跨域问题限制

    JSON是一种轻量级的数据交换格式,ECMA的一个子集

    优点:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)

    8.看下列代码输出为何?解释原因。

    var a;
    alert(typeof a); // undefined
    alert(b); // 报错
    로그인 후 복사

    解释:Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined。而b由于未声明将报错。注意未申明的变量和声明了未赋值的是不一样的。

    9.看下列代码,输出什么?解释原因。

    var a = null;
    alert(typeof a); //object
    로그인 후 복사

    解释:null是一个只有一个值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回”object”。

    10.看下列代码,输出什么?解释原因。

    var undefined;
    undefined == null; // true
    1 == true;   // true
    2 == true;   // false
    0 == false;  // true
    0 == &#39;&#39;;     // true
    NaN == NaN;  // false
    [] == false; // true
    [] == ![];   // true
    로그인 후 복사
    • undefined与null相等,但不恒等(===)

    • 一个是number一个是string时,会尝试将string转换为number

    • 尝试将boolean转换为number,0或1

    • 尝试将Object转换成number或string,取决于另外一个对比量的类型

    • 所以,对于0、空字符串的判断,建议使用 “===” 。“===”会先判断两边的值类型,类型不匹配时为false。

    那么问题来了,看下面的代码,输出什么,foo的类型为什么?

    var foo = "11"+2-"1";
    console.log(foo);
    console.log(typeof foo);
    로그인 후 복사

    执行完后foo的值为111,foo的类型为Number。

    var foo = "11"+2+"1";    //体会加一个字符串&#39;1&#39; 和 减去一个字符串&#39;1&#39;的不同
    console.log(foo);
    console.log(typeof foo);
    로그인 후 복사

    执行完后foo的值为1121(此处是字符串拼接),foo的类型为String。

    11.看代码给答案。

    var a = new Object();
    a.value = 1;
    b = a;
    b.value = 2;
    alert(a.value);
    로그인 후 복사

    答案:2(考察引用数据类型细节

    12.已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。

    答案:alert(stringArray.join(" "))

    那么问题来了,已知有字符串foo="get-element-by-id",写一个function将其转化成驼峰表示法"getElementById"。

    function combo(msg){
        var arr = msg.split("-");
        var len = arr.length;    //将arr.length存储在一个局部变量可以提高for循环效率
        for(var i=1;i<len;i++){
            arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);
        }
        msg=arr.join("");
        return msg;
    }
    로그인 후 복사

    (考察基础API)

    13.var numberArray = [3,6,2,4,1,5]; (考察基础API)

      1) 实现对该数组的倒排,输出[5,1,4,2,6,3]

      2) 实现对该数组的降序排列,输出[6,5,4,3,2,1]

    var numberArray = [3,6,2,4,1,5];
    numberArray.reverse(); // 5,1,4,2,6,3
    numberArray.sort(function(a,b){  //6,5,4,3,2,1
       return b-a; 
    })
    로그인 후 복사

    14.输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26

    var d = new Date();
    // 获取年,getFullYear()返回4位的数字
    var year = d.getFullYear();
    // 获取月,月份比较特殊,0是1月,11是12月
    var month = d.getMonth() + 1;
    // 变成两位
    month = month < 10 ? &#39;0&#39; + month : month;
    // 获取日
    var day = d.getDate();
    day = day < 10 ? &#39;0&#39; + day : day;
    alert(year + &#39;-&#39; + month + &#39;-&#39; + day);
    로그인 후 복사

    15.将字符串”{$id}{$name}”中的{$id}替换成10,{$name}替换成Tony (使用正则表达式)

    答案:"{$id}{$id}_{$name}".replace(/{\$id}/g, '10').replace(/{\$name}/g, ‘Tony’);

    16.为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义

    function escapeHtml(str) {
    return str.replace(/[<>”&]/g, function(match) {
        switch (match) {
                       case “<”:
                          return “<”;
                       case “>”:
                          return “>”;
                       case “&”:
                          return “&”;
                       case “\””:
                          return “"”;
          }
      });
    }
    로그인 후 복사

    17.foo = foo||bar ,这行代码是什么意思?为什么要这样写?

    答案:if(!foo) foo = bar; //如果foo存在,值不变,否则把bar的值赋给foo。

    短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。

    18.看下列代码,将会输出什么?(变量声明提升)

    var foo = 1;
    function(){
        console.log(foo);
        var foo = 2;
        console.log(foo);
    }
    로그인 후 복사

    答案:输出undefined 和 2。上面代码相当于:

    var foo = 1;
    function(){
        var foo;
        console.log(foo); //undefined
        foo = 2;
        console.log(foo); // 2;   
    }
    로그인 후 복사

    函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分。

    19.用js实现随机选取10--100之间的10个数字,存入一个数组,并排序。

    var iArray = []; 
    funtion getRandom(istart, iend){
            var iChoice = iend - istart +1;
            return Math.floor(Math.random() * iChoice + istart);
    }
    for(var i=0; i<10; i++){
            iArray.push(getRandom(10,100));
    }
    iArray.sort();
    로그인 후 복사

    20.把两个数组合并,并删除第二个元素。

    var array1 = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;];
    var bArray = [&#39;d&#39;,&#39;e&#39;,&#39;f&#39;];
    var cArray = array1.concat(bArray);
    cArray.splice(1,1);
    로그인 후 복사

    21.怎样添加、移除、移动、复制、创建和查找节点(原生JS,实在基础,没细写每一步)

    1)创建新节点

    • createDocumentFragment() //创建一个DOM片段

    • createElement() //创建一个具体的元素

    • createTextNode() //创建一个文本节点

    2)添加、移除、替换、插入

    • appendChild() //添加

    • removeChild() //移除

    • replaceChild() //替换

    • insertBefore() //插入

    3)查找

    • getElementsByTagName() //通过标签名称

    • getElementsByName() //通过元素的Name属性的值

    • getElementById() //通过元素Id,唯一性

    22.有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:'1', b:'2', c:'', d:'xxx', e:undefined}。

    答案:

    function serilizeUrl(url) {
        var result = {};
        url = url.split("?")[1];
        var map = url.split("&");
        for(var i = 0, len = map.length; i < len; i++) {
            result[map[i].split("=")[0]] = map[i].split("=")[1];
        }
        return result;
    }
    로그인 후 복사

    23.正则表达式构造函数var reg=new RegExp("xxx")与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?

    答案:当使用RegExp()构造函数的时候,不仅需要转义引号(即\"表示"),并且还需要双反斜杠(即\\表示一个\)。使用正则表达字面量的效率更高。

    邮箱的正则匹配:

    var regMail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
    로그인 후 복사

    24.看下面代码,给出输出结果。

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

    答案:4 4 4。

    原因:Javascript事件处理器在线程空闲之前不会运行。那么问题来了,如何让上述代码输出1 2 3?

    for(var i=1;i<=3;i++){
       setTimeout((function(a){  //改成立即执行函数
           console.log(a);    
       })(i),0);  
    };
    
    1           //输出
    2
    3
    로그인 후 복사

    25.写一个function,清除字符串前后的空格。(兼容所有浏览器)

    使用自带接口trim(),考虑兼容性:

    if (!String.prototype.trim) { 
     String.prototype.trim = function() { 
     return this.replace(/^\s+/, "").replace(/\s+$/,"");
     } 
    } 
    
    // test the function 
    var str = " \t\n test string ".trim(); 
    alert(str == "test string"); // alerts "true"
    로그인 후 복사

    26.Javascript中callee和caller的作用?

    答案:

    caller是返回一个对函数的引用,该函数调用了当前函数;

    callee是返回正在被执行的function函数,也就是所指定的function对象的正文。

    那么问题来了?如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子?(使用callee完成)

    var result=[];
    function fn(n){  //典型的斐波那契数列
       if(n==1){
            return 1;
       }else if(n==2){
               return 1;
       }else{
            if(result[n]){
                    return result[n];
            }else{
                    //argument.callee()表示fn()
                    result[n]=arguments.callee(n-1)+arguments.callee(n-2);
                    return result[n];
            }
       }
    }
    로그인 후 복사

    中级Javascript:

    1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

    • 考察点1:对于基本数据类型和引用数据类型在内存中存放的是值还是指针这一区别是否清楚

    • 考察点2:是否知道如何判断一个变量是什么类型的

    • 考察点3:递归算法的设计

    // 方法一:
    Object.prototype.clone = function() {
        var o = this.constructor === Array ? [] : {};
        for (var e in this) {
            o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
        }
        return o;
    }
    
    //方法二:
    /**
     * 克隆一个对象
     * @param Obj
     * @returns
     */
    function clone(Obj) {
        var buf;
        if (Obj instanceof Array) {
            buf = []; //创建一个空的数组 
            var i = Obj.length;
            while (i--) {
                buf[i] = clone(Obj[i]);
            }
            return buf;
        } else if (Obj instanceof Object) {
            buf = {}; //创建一个空对象 
            for (var k in Obj) { //为这个对象添加新的属性 
                buf[k] = clone(Obj[k]);
            }
            return buf;
        } else { //普通变量直接赋值
            return Obj;
        }
    }
    로그인 후 복사

    2.如何消除一个数组里面重复的元素?

    var arr = [1, 2, 3, 3, 4, 4, 5, 5, 6, 1, 9, 3, 25, 4];
    
    function deRepeat() {
        var newArr = [];
        var obj = {};
        var index = 0;
        var l = arr.length;
        for (var i = 0; i < l; i++) {
            if (obj[arr[i]] == undefined) {
                obj[arr[i]] = 1;
                newArr[index++] = arr[i];
            } else if (obj[arr[i]] == 1)
                continue;
        }
        return newArr;
    
    }
    var newArr2 = deRepeat(arr);
    alert(newArr2); //输出1,2,3,4,5,6,9,25
    로그인 후 복사

    3.小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:

    function Dog() {
           this.wow = function() {
                   alert(’Wow’);
          }
           this.yelp = function() {
                  this.wow();
          }
    }
    로그인 후 복사

    小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实。继承,原型,setInterval

    答案:

    function MadDog() {
        this.yelp = function() {
              var self = this;          
              setInterval(function() {
                    self.wow();      
              }, 500);
          }
    }
    MadDog.prototype = new Dog();         
    
    //for test
    var dog = new Dog();
    dog.yelp();
    var madDog = new MadDog();
    madDog.yelp();
    로그인 후 복사

    4.下面这个ul,如何点击每一列的时候alert其index?(闭包)

    <ul id=”test”>
        <li>这是第一条</li>
        <li>这是第二条</li>
        <li>这是第三条</li>
    </ul>
    로그인 후 복사

    答案:

    // 方法一:
    var lis=document.getElementById(&#39;2223&#39;).getElementsByTagName(&#39;li&#39;);
    for(var i=0;i<3;i++)
    {
        lis[i].index=i;
        lis[i].onclick=function(){
            alert(this.index);
        };
    }
    
    //方法二:
    var lis=document.getElementById(&#39;2223&#39;).getElementsByTagName(&#39;li&#39;);
    for(var i=0;i<3;i++)
    {
        lis[i].index=i;
        lis[i].onclick=(function(a){
            return function() {
                alert(a);
            }
        })(i);
    }
    로그인 후 복사

    5.编写一个JavaScript函数,输入指定类型的选择器(仅需支持id,class,tagName三种简单CSS选择器,无需兼容组合选择器)可以返回匹配的DOM节点,需考虑浏览器兼容性和性能。

    答案:

    var query = function(selector) {
                    var reg = /^(#)?(\.)?(\w+)$/img;
                    var regResult = reg.exec(selector);
                    var result = [];
                    //如果是id选择器
                    if(regResult[1]) {
                        if(regResult[3]) {
                            if(typeof document.querySelector === "function") {
                                result.push(document.querySelector(regResult[3]));
                            }
                            else {
                                result.push(document.getElementById(regResult[3]));
                            }
                        }
                    }
                    //如果是class选择器
                    else if(regResult[2]) {
                        if(regResult[3]) {
                            if(typeof document.getElementsByClassName === &#39;function&#39;) {
                                var doms = document.getElementsByClassName(regResult[3]);
                                if(doms) {
                                    result = converToArray(doms);
                                }
                            }
                            //如果不支持getElementsByClassName函数
                            else {
                                var allDoms = document.getElementsByTagName("*") ;
                                for(var i = 0, len = allDoms.length; i < len; i++) {
                                    if(allDoms[i].className.search(new RegExp(regResult[2])) > -1) {
                                        result.push(allDoms[i]);
                                    }
                                }
                            }
                        }
                    }
                    //如果是标签选择器
                    else if(regResult[3]) {
                        var doms = document.getElementsByTagName(regResult[3].toLowerCase());
                        if(doms) {
                            result = converToArray(doms);
                        }
                    }
                    return result;
                }
    
                function converToArray(nodes){
                      var array = null;         
                      try{        
                            array = Array.prototype.slice.call(nodes,0);//针对非IE浏览器         
                      }catch(ex){
                          array = new Array();         
                          for( var i = 0 ,len = nodes.length; i < len ; i++ ) { 
                              array.push(nodes[i])         
                          }         
                      }      
                      return array;
              }
    로그인 후 복사

    6.请评价以下代码并给出改进意见。

    if(window.addEventListener){
        var addListener = function(el,type,listener,useCapture){
            el.addEventListener(type,listener,useCapture);
      };
    }
    else if(document.all){
        addListener = function(el,type,listener){
            el.attachEvent("on"+type,function(){
              listener.apply(el);
          });
       }  
    }
    로그인 후 복사

    评价:

    • 不应该在if和else语句中声明addListener函数,应该先声明;

    • 不需要使用window.addEventListener或document.all来进行检测浏览器,应该使用能力检测;

    • 由于attachEvent在IE中有this指向问题,所以调用它时需要处理一下

    改进如下:

    function addEvent(elem, type, handler) {  
        if (elem.addEventListener) {    
            elem.addEventListener(type, handler, false);  
        } else if (elem.attachEvent) {    
            elem[&#39;temp&#39; + type + handler] = handler;    
            elem[type + handler] = function() {    
                elem[&#39;temp&#39; + type + handler].apply(elem);  
            };  
            elem.attachEvent(&#39;on&#39; + type, elem[type + handler]); 
        } else {  
            elem[&#39;on&#39; + type] = handler;  
        }
    }
    로그인 후 복사

    7.给String对象添加一个方法,传入一个string类型的参数,然后将string的每个字符间价格空格返回,例如:

    addSpace("hello world") // -> 'h e l l o w o r l d'

    String.prototype.spacify = function() {
        return this.split(&#39;&#39;).join(&#39; &#39;);
    };
    로그인 후 복사

    接着上述答题,那么问题来了

    1)直接在对象的原型上添加方法是否安全?尤其是在Object对象上。(这个我没能答出?希望知道的说一下。) 

    2)函数声明与函数表达式的区别? 

    答案:在Javscript中,解析器在向执行环境中加载数据时,对函数声明和函数表达式并非是一视同仁的,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问),至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。(函数声明提升)

    8.定义一个log方法,让它可以代理console.log的方法。

    可行的方法一:

    function log(msg)  {
        console.log(msg);
    }
    log("hello world!") // hello world!
    로그인 후 복사

    如果要传入多个参数呢?显然上面的方法不能满足要求,所以更好的方法是:

    function log() {
        console.log.apply(console, arguments);
    };
    로그인 후 복사

    那么问题来了,apply和call方法的异同?  

    答案:

    对于apply和call两者在作用上是相同的,即是调用一个对象的一个方法,以另一个对象替换当前对象。将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

    但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3]) 。

    9.在Javascript中什么是伪数组?如何将伪数组转化为标准数组?

    答案:

    伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。

    假设接第八题题干,我们要给每个log方法添加一个"(app)"前缀,比如'hello world!' ->'(app)hello world!'。方法如下:

    function log() {
        var args = Array.prototype.slice.call(arguments); //为了使用unshift数组方法,将argument转化为真正的数组
        args.unshift(&#39;(app)&#39;);
    
        console.log.apply(console, args);
    };
    로그인 후 복사

    10.对作用域上下文和this的理解,看下列代码:

    var User = {
        count: 1,
    
        getCount: function() {
            return this.count;
        }
    };
    console.log(User.getCount()); // what?
    var func = User.getCount;
    console.log(func()); // what?
    로그인 후 복사

    问两处 console 输出什么?为什么?

    答案是 1 和 undefined。

    func 是在 winodw 的上下文中被执行的,所以会访问不到 count 属性。

    那么问题来了,如何确保Uesr总是能访问到func的上下文,即正确返回1

    答案:正确的方法是使用Function.prototype.bind。兼容各个浏览器完整代码如下:

    Function.prototype.bind = Function.prototype.bind || function(context) {
        var self = this;
    
        return function() {
            return self.apply(context, arguments);
        };
    }
    
    var func = User.getCount.bind(User);
    console.log(func());
    로그인 후 복사

    11.原生JS的window.onload与Jquery的$(document).ready(function(){})有什么不同?如何用原生JS实现Jq的ready方法?

    window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行。

    $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。   

    /*
     * 传递函数给whenReady()
     * 当文档解析完毕且为操作准备就绪时,函数作为document的方法调用
     */
    var whenReady = (function() { //这个函数返回whenReady()函数
        var funcs = []; //当获得事件时,要运行的函数
        var ready = false; //当触发事件处理程序时,切换为true
    
        //当文档就绪时,调用事件处理程序
        function handler(e) {
            if (ready) return; //确保事件处理程序只完整运行一次
    
            //如果发生onreadystatechange事件,但其状态不是complete的话,那么文档尚未准备好
            if (e.type === &#39;onreadystatechange&#39; && document.readyState !== &#39;complete&#39;) {
                return;
            }
    
            //运行所有注册函数
            //注意每次都要计算funcs.length
            //以防这些函数的调用可能会导致注册更多的函数
            for (var i = 0; i < funcs.length; i++) {
                funcs[i].call(document);
            }
            //事件处理函数完整执行,切换ready状态, 并移除所有函数
            ready = true;
            funcs = null;
        }
        //为接收到的任何事件注册处理程序
        if (document.addEventListener) {
            document.addEventListener(&#39;DOMContentLoaded&#39;, handler, false);
            document.addEventListener(&#39;readystatechange&#39;, handler, false); //IE9+
            window.addEventListener(&#39;load&#39;, handler, false);
        } else if (document.attachEvent) {
            document.attachEvent(&#39;onreadystatechange&#39;, handler);
            window.attachEvent(&#39;onload&#39;, handler);
        }
        //返回whenReady()函数
        return function whenReady(fn) {
            if (ready) {
                fn.call(document);
            } else {
                funcs.push(fn);
            }
        }
    })();
    로그인 후 복사

    如果上述代码十分难懂,下面这个简化版:

    function ready(fn){
        if(document.addEventListener) {        //标准浏览器
            document.addEventListener(&#39;DOMContentLoaded&#39;, function() {
                //注销事件, 避免反复触发
                document.removeEventListener(&#39;DOMContentLoaded&#39;,arguments.callee, false);
                fn();            //执行函数
            }, false);
        }else if(document.attachEvent) {        //IE
            document.attachEvent(&#39;onreadystatechange&#39;, function() {
                if(document.readyState == &#39;complete&#39;) {
                    document.detachEvent(&#39;onreadystatechange&#39;, arguments.callee);
                    fn();        //函数执行
                }
            });
        }
    };
    로그인 후 복사

    12.(设计题)想实现一个对页面某个节点的拖曳?如何做?(使用原生JS)

    回答出概念即可,下面是几个要点

    • 给需要拖拽的节点绑定mousedown, mousemove, mouseup事件

    • mousedown事件触发后,开始拖拽

    • mousemove时,需要通过event.clientX和clientY获取拖拽位置,并实时更新位置

    • mouseup时,拖拽结束

    • 需要注意浏览器边界的情况

    13.

    function setcookie(name, value, days) { //给cookie增加一个时间变量
          
        var exp = new Date();  
        exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000); //设置过期时间为days天
          
        document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
    }
    
    function getCookie(name) {  
        var result = "";  
        var myCookie = "" + document.cookie + ";";  
        var searchName = "+name+" = ";  
        var startOfCookie = myCookie.indexOf(searchName);  
        var endOfCookie;  
        if (satrtOfCookie != -1) {    
            startOfcookie += searchName.length;    
            endOfCookie = myCookie.indexOf(";", startOfCookie);    
            result = (myCookie.substring(startOfCookie, endOfCookie));  
        }  
        return result;
    }
    (function() {  
        var oTips = document.getElementById(&#39;tips&#39;); //假设tips的id为tips
          
        var page = {  
            check: function() { //检查tips的cookie是否存在并且允许显示
                    
                var tips = getCookie(&#39;tips&#39;);    
                if (!tips || tips == &#39;show&#39;) return true; //tips的cookie不存在
                    
                if (tips == "never_show_again") return false;  
            },
              hideTip: function(bNever) {    
                if (bNever) setcookie(&#39;tips&#39;, &#39;never_show_again&#39;, 365);    
                oTips.style.display = "none"; //隐藏
                  
            },
              showTip: function() {  
                oTips.style.display = "inline"; //显示,假设tips为行级元素
                  
            },
              init: function() {    
                var _this = this;    
                if (this.check()) {    
                    _this.showTip();    
                    setcookie(&#39;tips&#39;, &#39;show&#39;, 1);  
                }  
                oTips.onclick = function() {    
                    _this.hideTip(true);  
                };  
            }  
        };
        page.init();
    })();
    로그인 후 복사

    14.说出以下函数的作用是?空白区域应该填写什么?

    //define 
    (function(window) {
        function fn(str) 
            this.str = str;
        }
    
        fn.prototype.format = function() {
            var arg = ______;
            return this.str.replace(_____, function(a, b) {
                return arg[b] || "";
            });
        }
        window.fn = fn;
    })(window);
    
    //use
    (function() {
        var t = new fn(&#39;<p><a href="{0}">{1}</a><span>{2}</span></p>&#39;);
        console.log(t.format(&#39;http://www.alibaba.com&#39;, &#39;Alibaba&#39;, &#39;Welcome&#39;));
    })();
    로그인 후 복사

    答案:访函数的作用是使用format函数将函数的参数替换掉{0}这样的内容,返回一个格式化后的结果:

    第一个空是:arguments
    第二个空是:/\{(\d+)\}/ig

    15.用面向对象的Javascript来介绍一下自己。(没答案哦亲,自己试试吧)

    答案: 对象或者Json都是不错的选择哦。

    16.讲解原生Js实现ajax的原理。

    Ajax 的全称是Asynchronous JavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式。

    Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。

    XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。

    XMLHttpRequest这个对象的属性有:

    • onreadystatechang 每次状态改变所触发事件的事件处理程序。

    • responseText 从服务器进程返回数据的字符串形式。

    • responseXML 从服务器进程返回的DOM兼容的文档数据对象。

    • status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)

    • status Text 伴随状态码的字符串信息

    • readyState 对象状态值

      • 0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)

      • 1 (初始化) 对象已建立,尚未调用send方法

      • 2 (发送数据) send方法已调用,但是当前的状态及http头未知

      • 3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,

      • 4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据

      下面简单封装一个函数:

    ajax({
            url: "./TestXHR.aspx",              //请求地址
            type: "POST",                       //请求方式
            data: { name: "super", age: 20 },        //请求参数
            dataType: "json",
            success: function (response, xml) {
                // 此处放成功后执行的代码
            },
            fail: function (status) {
                // 此处放失败后执行的代码
            }
        });
    
        function ajax(options) {
            options = options || {};
            options.type = (options.type || "GET").toUpperCase();
            options.dataType = options.dataType || "json";
            var params = formatParams(options.data);
    
            //创建 - 非IE6 - 第一步
            if (window.XMLHttpRequest) {
                var xhr = new XMLHttpRequest();
            } else { //IE6及其以下版本浏览器
                var xhr = new ActiveXObject(&#39;Microsoft.XMLHTTP&#39;);
            }
    
            //接收 - 第三步
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    var status = xhr.status;
                    if (status >= 200 && status < 300) {
                        options.success && options.success(xhr.responseText, xhr.responseXML);
                    } else {
                        options.fail && options.fail(status);
                    }
                }
            }
    
            //连接 和 发送 - 第二步
            if (options.type == "GET") {
                xhr.open("GET", options.url + "?" + params, true);
                xhr.send(null);
            } else if (options.type == "POST") {
                xhr.open("POST", options.url, true);
                //设置表单提交时的内容类型
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                xhr.send(params);
            }
        }
        //格式化参数
        function formatParams(data) {
            var arr = [];
            for (var name in data) {
                arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
            }
            arr.push(("v=" + Math.random()).replace("."));
            return arr.join("&");
        }
    로그인 후 복사

    上述代码大致表述了ajax的过程,释义自行google,问题未完,那么知道什么是Jsonp和pjax吗?

    答案:

    Jsonp:(JSON with Padding)是一种跨域请求方式。主要原理是利用了script 标签可以跨域请求的特点,由其 src 属性发送请求到服务器,服务器返回 js 代码,网页端接受响应,然后就直接执行了,这和通过 script 标签引用外部文件的原理是一样的。JSONP由两部分组成:回调函数和数据,回调函数一般是由网页端控制,作为参数发往服务器端,服务器端把该函数和数据拼成字符串返回。

    pjax:pjax是一种基于ajax+history.pushState的新技术,该技术可以无刷新改变页面的内容,并且可以改变页面的URL。(关键点:可以实现ajax无法实现的后退功能)pjax是ajax+pushState的封装,同时支持本地存储、动画等多种功能。目前支持jquery、qwrap、kissy等多种版本。

    暂且贴出做出答案的部分。针对文中各题,如有更好的解决方法或者错误之处,各位亲务必告知

위 내용은 BAT 주요 인터넷 기업의 JavaScript 프론트엔드 인터뷰 질문 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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