InterviewQuestions

155 阅读5分钟

1. 手写jsonp的实现?

jsonp原理:因为jsonp发送的并不是ajax请求,其实是动态创建script标签 script标签是没有同源限制的,把script标签的src指向请求的服务端地址。

function jsonp (url,data={},callback='callback') {
    //处理json对象,拼接url
    data.callback = callbak
    let params = []
    for(let key in data){
        params.push(key + '=' + data[key])
    }
    let script = document.creatElement('script')
    script.src = url + '?' + params.join('&')
    document.body.appendChild(script)
    
    //返回Promise
    return new Promise ((resolve,reject) => {
       window[callback] = (data) => {
           try{
               resolve (data)
           } catch(e){
               reject(e)
           } finally {
               //移除script元素
               script.parentNode.removeChild(script)
               console.log(script)
           }
       }
    })
}

//请求数据
jsonp('http://photo.sina.cn/aj/index',{
    page:1,
    cate:'recommend',
},'jsoncallback').then(data => {
    console.log(data)
})

若需要防盗用,可用referer检查,即:

if(request.headers["referer"].indexOf("http://frank.com:8080"====){
  response.statusCode = 200;
  response.setHeader("Content-Type","text/javascript;charset=utf-8");
  const string = fs.readFileSync("./public/friends.js").toString();
  // 或改成: const string = `window['{{xxx}}']({{data}})`;
  const data = fs.readFileSync("./public/friends.json").toString();
  const string2 =string.replace("{{data}}",data).replace('{{xxx}}',query.functionName);
  response.wtite(string2);
  response
} else {
  response.statusCode = 404;
  response.end();
}  

2. 一个200*200的div在不同分辨率屏幕上下左右居中,用CSS实现?

style:{
  position: absolute;
  height: 200px;
  width: 200px;
  background-color: yellow; 
  top: 50%;
  left: 50%;
  margin-left: -100px;
  margin-top: -100px;
} 或:{
   position: absolute;
   height: 200px;
   width: 200px;
   top: 0;
   left: 0;
   bottom: 0;
   right: 0;
   margin: auto;
   background-color: yellow;  
  }

3.写一个左中右布局占满屏幕,其中左右两块是固定宽度200,中间自适应宽,要求先加载中间块,请写出结构及样式?

用flex或float都可实现

  <body>
    <div class="left">left</div>
    <div class="center">center</div>
    <div class="right">right</div>
  </body>
 <style>
    * {
       margin: 0;
       padding: 0;
     }
    html,body {
       height: 100%;
     }
    body {
       display: flex;
     }
    .left {
       width: 100px;
       background-color: rgb(199, 170, 223);
     }
    .center {
       background-color: rgb(151, 228, 148);
       flex: 1;
     }
    .right {
       width: 100px;
       background-color: rgb(199, 170, 223);
     }
  </style>

或float:

 <body>
   <div class="left">left</div>
   <div class="right">right</div>
   <div class="center">center</div>
 </body>
 <style>
  * {
     margin: 0;
     padding: 0;
   }
   html,body {
   height: 100%;
   }
  .left {
     width: 100px;
     background-color: rgb(199, 170, 223);
     float: left;
     height: 100%;
   }
  .center {
     background-color: rgb(151, 228, 148);
     overflow: hidden;
     height: 100%;
   }
  .right {
     width: 100px;
     background-color: rgb(199, 170, 223);
     float: right;
     height: 100%;
   }
 </style>

或:

 <h3>实现三列宽度自适应布局</h3>  
       <div id = "left">我是左边</div>  
       <div id = "right">我是右边</div>  
       <div id = "center">我是中间</div>
<style>:
html,body{ margin: 0px;width: 100%; }  
h3{height: 100px;margin:20px 0 0;}  
#left,#right{width: 200px;height: 200px; background-color: #ffe6b8;position: absolute;top: 120px;}  
#left{left:0px;}  
#right{right: 0px;}  
#center{margin:2px 210px ;background-color: #eee;height: 200px; } 

4. 阐述清除浮动的几种方式?

不清除浮动会怎样? (1):背景不能显示 (2):边框不能撑开 (3):margin 设置值不能正确显示 (4):下方内容往上移盖住浮动区域的内容

html代码:

<div class="container">   
 <div class="fl"></div>    
 <div class="fr"></div>
</div>
<style>
    .fl{float:left;}
    .fr{float:right;}
</style>
方式1:

在.container下,最后一个div后面再加一个空div如下:

方式2: 伪类清除浮动:after:

.container:after{
    content:'';
    display: block;
    clear: both;
    height:0;
    width:100%;
    visibility: hidden;
}
.container{ zoom:1; //为了兼容IE}

方法3: 双伪类清除浮动:

.container:before,.container:after {
    content: "";
    display: block;
    clear: both;
}
.container{
    zoom: 1;
}

方式4: 展现为表格,需设置宽度:

.container{
    width:100%;
    display:table;
}

方式5: 展现为内联块状,需设置宽度:

.container{
    width:100%;
    display:inline-block;
}

方式6: 给父元素.container添加样式: overflow:hidden; 缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。(不建议使用此种方式,可能会影响页面元素布局) 方式7: 给父元素.container添加样式:

.container{
    overflow: auto;
    zoom: 1;
}不推荐使用,如果需要出现滚动条或者确保代码不会出现滚动条才使用。

5. 如何用原生js给一个按钮绑定两个onclick事件?

 <button id ="btn">按钮</button>
 <script>
    // 事件监听 绑定多个事件
    var btn = document.getElementById("btn");
    btn4.addEventListener("click",hello1);
    btn4.addEventListener("click",hello2);
    function hello1(){
         alert("hello1");
   }
    function hello2(){
          alert("hello2");
   }
 </script>  

6. 拖曳会用到哪些事件?

ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上
ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上
ondragover 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondragleave 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondrop 事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
ondragend 事件:当拖拽完成后触发的事件,此事件作用在被拖曳元素上
event.preventDefault() 方法:阻止默认的些事件方法等执行。在ondragover中一定要执行 preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用用document的ondragover事件把它直接干掉。
event.setDataTransfer.effectAllowed 属性:就是拖拽的效果。
evetn.setDataTransfer.setDragImage() 方法:指定图片或者文档元素做拖动时的视觉效果。

7. 请描述一下 cookie sessionStorage和localstorage区别?

共同点:SessionStorage, LocalStorage, Cookie这三者都可以被用来在浏览器端存储数据,而且都是字符串类型的键值对。 区别在于前两者属于WebStorage,创建它们的目的便于客户端存储数据。 而Cookie早在网景公司的浏览器中就开始支持,最初目的是为了保持HTTP的状态,是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。 区别: 1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。 2.存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。 3.数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 4.作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。 5.Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。 6.Web Storage 的 api 接口使用更方便。

8. 计算一个数组arr所有元素的和?

 function sum(){
    var  all=0;
    for (var i=0;i<arguments.length;i++) {
      if (typeof(arguments[i]=="number")) {
      all += arguments[i];
      }
    }
    return all;
 }
 document.write(sum(1,2,3,4)+'<br/>');

方法二:

function sum2(arr){
   var all=0;
   for (var i=0;i<arr.length;i++) {
     if (typeof arr[i]=="number") {
        all += arr[i];
        }
     }
     return all;
   }
document.write(sum2([1,2,3,4]));

方法三:

var arr1=[1,2,3,4,5,6,7,8,9];
var sum1=0;
for (var i=0;i<=arr1.length;i++) {
   if (typeof arr1[i]=="number") {
     sum1 += arr1[i];

   }
}
 document.write(sum1);
  1. 编写一个方法去掉数组里面重复的内容 var arr=[1,2,3,4,5,1,2]? 方法一:
var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
   if( !obj[arr[i]] ){
     obj[arr[i]] = 1;
     tmp.push(arr[i]);
   }
}
console.log(tmp);

方法二:

 var arr = [2,3,4,4,5,2,3,6] , arr2 = []
 for(var i=0; i< arr.length; i++){
    if(arr2.indexOf(arr[i])< 0){
       arr2.push(arr[i];
    }
 }
 console.log(arr2) 

方法三:

  var arr = [2,3,4,4,5,2,3,6];
  var arr2 = arr.filter(function(element,index,self){
     return self.indexOf(element) === index;
  });
  console.log(arr2);

冒泡排序:从大到小

<script>
     // 冒泡排序 var arr = [5, 4, 3, 2, 1];
      var arr = [4, 1, 2, 3, 5];
      for (var i = 0; i <= arr.length - 1; i++) { // 外层循环管趟数 
          for (var j = 0; j <= arr.length - i - 1; j++) { 
	   // 里面的循环管 每一趟的交换次数
           // 内部交换2个变量的值 前一个和后面一个数组元素相比较
              if (arr[j] < arr[j + 1]) {
                  var temp = arr[j];
                  arr[j] = arr[j + 1];
                  arr[j + 1] = temp;
              }

          }
      }
      console.log(arr);
  </script>

利用函数求任意个数的最大值:

 <script>
    // 利用函数求任意个数的最大值
   function getMax() { // arguments = [1,2,3]
     var max = arguments[0];
     for (var i = 1; i < arguments.length; i++) {
       if (arguments[i] > max) {
           max = arguments[i];
        }
     }
     return max;
   }
   console.log(getMax(1, 2, 3));
   console.log(getMax(1, 2, 3, 4, 5));
   console.log(getMax(11, 2, 34, 444, 5, 100));
   </script>

10. document.write 和 innerHTML的区别?

1.write是DOM方法,向文档写入HTML表达式或JavaScript代码,可列出多个参数,参数被顺序添加到文档中;innerHTML是DOM属性,设置或返回调用元素开始结束标签之间的HTML元素。 2.两者都可向页面输出内容,innerHTML比document.write更灵活。当文档加载时调用document.write直接向页面输出内容,文档加载结束后调用document.write输出内容会重写整个页面。 通常按照两种方式使用write()方法:一是在使用该方法在文档中输出HTML,二是在调用该方法的的窗口之外的窗口、框架中产生新文档(务必使用close关闭文档)。在读模式下,innerHTML属性返回与调用元素的所有子节点对应的HTML标记,在写模式下,innerHTML会根据指定的值创建新的DOM树替换调用元素原先的所有子节点。 3.两者都可动态包含外部资源如JavaScript文件 通过document.write插入

  <body>
   <p>原有内容</p>
   <div id="testdiv">原有内容</div>
  </body>
  JavaScriptwindow.onload = function() {
     var testdiv=document.getElementById('testdiv');
     testdiv.innerHTML = "<p>I love <em>JavaScript</em>!</p>";
  }和
  window.onload = function() {
    document.write("现有内容");
  }测试
  1. vue.js生命周期? beforeCreate created beforeMount mounted beforeUpdate update beforeDestroy destroyed