zoukankan      html  css  js  c++  java
  • 2019-09-09 JS面试题(持续更新中)

    1、JS 中的 MUL 函数

    function mul(x){
        return function(y){
             return function(z){
                  return x*y*z
             }
        } 
    }
    var result = mul(2)(3)(4);
    console.log(result,'result');//24
    

    2、JS 中 slice 和 splice 的区别?

    var arr = [0,1,2,3,4,5,6,7,8,9];
    console.log(arr.slice(2,9));//[2,3,4,5,6,7,8],如果此时打印arr,显示的数据结构并未发生改变,和之前的值是一样的。
    console.log(arr.splice(2,9));//[2,3,4,5,6,7,8,9]; 如果此时打印arr,的数据,显示的结果是 [0,1]。数据结构已经发生改变了。

         总结一下:

          slice(start,end) 方法,返回一个新数组,包含从 start 到end(不包含该元素) 的数组元素。(索引从0开始且 不会改变原数组,而是返回一个子数组)。

               start 参数:必须,规定从哪个位置开始选取,如果为负数,规定从数组的尾部开始选取,-1是指最后一个元素。

               end  参数:可选。如果没有这个参数的话,那么指的是从start开始到数组结束的所有元素,如果这个参数为负数,那么规定是从数组尾部开始算起的元素。

          splice():该方法向或者从数组中添加或者删除,返回被删除的数据。(该方法会改变原数组)

               splice(index,howmany,item1,...itemx):

                    index 参数:必须,整数,规定添加或删除的位置,使用负数的话,则表示从数组的尾部开始。

                    howmany 参数:必须,要删除的数量,如果为0,则不删除数据。

                    item1...itemx 参数:可选,向数组添加的新数据。

         例如:

    var  testArray = [0,1,2,3,4,5];
    console.log(testArray.splice(2,2,'hello','world'));//[2,3]
    console.log(testArray);//[0,1,'hello','world',4,5]

    3、JS 中的展开运算符操作?

    var mids = ['hello','world'];
    var newMids = [1,2,3,..mids,4,5];
    console.log(newMids);//[1,2,3,'hello','world',4,5]

    4、JS 中的函数提升?

         JS 中创建函数有2中方法, 函数声明  和  函数表达式。

         函数声明:          

    fn();//这个是函数声明
    
    function fn(){
       console.log('这个是函数声明')
    }

         函数表达式:

    fns();// 报错, fns is not a function
     
    var fns = function(){
        console.log('这个是函数表达式')
    }

         由此说明:函数声明的优先级要高于函数表达式。

    5、JS 中的 typeof  返回哪些数据类型?

          string  , boolean  , number, undefined  , null, object ,symbol (es6)。

    6、强制类型转换 和 隐式类型转换?

          parseInt   parseFloat   number    和   ==    ===

    7、添加,删除,替换,插入 到某个节点的方法

    1)创建新节点
    
         createElement()//创建一个具体的元素
         createTextNode()//创建一个文本节点
         例如:
         元素获取body:
               var body = document.getElementsByTagName("body")[0];
               (或者   var body = document.body;)
               var div = document.createElement('div');
               div.className='create_div';
               body.appendChild(div);  //创建完毕。
               var texts = document.createTextNode('hello world');
               div.appendChild(texts);   //创建完毕。     
    
    2)添加,移出,替换,插入
         appendChild()//添加
         removeChild()//移除
         replaceChild()//替换
         insertBefore()//插入
    
    3)查找
         getElementsByTagName()//标签名称
         getElementsByName()//元素的Name 属性的值
         getElementById()//元素id ,唯一性。
         

    8、看下面代码输出结果?

    for(var i =0;i<5;i++){
        setTimeout(function(){
           console.log(i)
        },1000)
    }
    //5,5,5,5,5

    解决办法:(8.1)将  var 变为 let  即可。

                     (8.2)使用闭包

    for(var i=0;i<=5;i++){
        setTimeout(function(){
            console.log(i)
        }(i),1000)
    }
    //0,1,2,3,4,5

                    (8.3)

    
    
    for (var i = 0; i < 5; i++) {
         (function () {
            var j = i;
            setTimeout(function () {
               console.log(j)
            }, 1000)
         })(i)
    }
    //0,1,2,3,4

     9、数组去重方法:

     双层for循环,Array.sort()加一行遍历冒泡,Array.filter() 加indexOf,ES6中的set去重,object键值对去重。    
    function duplicateRemoval(arr){   //双层for循环
        for(let i=0;i<arr.length;i++){
           for(let j=i+1;j<arr.length;j++){
                 if(arr[i]==arr[j]){
                       arr.splice(j,1);
                       j--;
                 }
           }
        }
        return arr;
    }
    // es6 中的 set去重
    function unique(arr){
       return Array.from(new Set(arr))    //或者  return [...new Set(arr)]
    }
    //Array.from()方法:就是一个类数组对象或者可遍历对象转换成一个真正的数组。(最基本要求是具有length属性的对象。)
    
    //利用indexOf 去重   以及 includes (异曲同工之妙),如果有的话,则返回true,反之为false表示没有。
    function unique(arr){
       if(!Array.isArray(arr)){  //用来判断是否是数组
          return
       }
       let array = [];
       for(let i=0;i<arr.length;i++){
          if(array.indexOf(arr[i]===-1)){  //这里表示没有==> 也可以换成 这样子表示:  if(!array.includes(arr[i])){//表示没有}
             arrar.push(arr[i])
          }
       }
       return array;
    }
    //Array.filter()  过滤数组,方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,且不会改变原始数组。
    function unique(arr){
      return arr.filter(function(item,index,arr){
        return arr.indexOf(item,0)===index;   //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素。
      })
    }

     10、数组的方法

           push() 向数组的末尾添加一个或多个元素,并返回新的长度。

           pop()  删除向数组末尾的一个元素,并把他作为返回值返回。

           unshift() 向数组的头添加一个元素或多个元素,并返回新的长度,向前边插入元素后,其他元素依次调整。

           shift()  删除数组头的一个元素,并把他作为返回值返回。

           slice(截取开始的索引,截取结束的索引)  向数组中提取指定元素。截取结束的索引可以不写,如果索引为负值的话,代表从后边开始计算。  

           splice(开始的索引,删除的数量)  删除数组中的指定元素,会影响原数组,并把删除的元素作为返回值返回。

           concat()   可以连接两个或多个数组,并返回新数组,不会影响原数组。

           join()   可以将数组转换为字符串。

           reverse()  用来反转数组,会影响原数组。

           sort()   用来对数组中的元素进行排序,影响原数组。

    11、测试 numbers 数组的内容是什么?

    const length = 4;
    const numbers = [];
    for(var i=0;i<length;i++);{ //注意看这里哦,多了一个分号
    numbers.push(i+1);
    }
    numbers;//
    for() 在空语句上进行4次迭代(不执行任何操作),而忽略实际将项目推入数组的块:{numbers.push(i+1);}
    //上面代码等同于:
    var i;
    for(i=0;i<length;i++){
    // do nothing;
    }{
    numbers.push(i+1);
    }
    numbers;//[5]

    12、意外的全局变量

    function foo(){
    let a = b = 0;
    a++;
    return a;
    }
    foo();
    typeof a;//'undefined'
    typeof b;//'number'

    //上面代码等效于:
    function foo(){
    let a;
    window.b = 0;
    a++;
    return a;
    }
    foo();
    typeof a;//undefined
    typeof b;//number

     13、http 协议与 https协议的区别:

    超文本传输协议HTTP协议被用于在web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了web浏览器和网站服务器之间的传输报文,
    就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号,密码等支付信息。
    为了解决HTTP协议这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和
    服务器之间的通信加密。

    HTTP和HTTPS的基本概念:
    HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准TCP,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
    HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
    HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

    HTTP和HTTPS区别:
    HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(secure sockets layer)协议用于对HTTP
    协议传输的数据进行加密,从而就有了HTTPS。简单来说,HTTPS协议是SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,要比HTTP协议安全。
    两者之间的主要区别是:
    HTTPS协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
    HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
    HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443.
    HTTP的连接很简单,是无状态的,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比HTTP协议安全。
    链接:https://www.cnblogs.com/sueyyyy/p/12012570.html

    14、如何产生闭包?   当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。【函数嵌套,内部函数引用了外部函数的数据(变量/函数)】

    闭包是什么?
    闭包是嵌套的内部函数。包含被引用变量(函数)的对象。【闭包存在于嵌套的内部函数中】
    例子:
    <---html代码 -->
    <body onload="init()">
    <p>one</p>
    <p>two</p>
    <p>three</p>
    <p>four</p>
    <p>five</p>
    </body>
    //js 代码
    function init(){ //将变量i保存在每个段落对象上
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    ps[i].i = i;
    ps[i].onclick = function(){
    console.log(this.i)
    }
    }
    }
    function init(){ //加一层闭包,i已函数参数形式传递给内层函数
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    (function(arg){
    ps[i].onclick = function(){
    console.log(arg);
    }
    })(i)
    }
    }

    function init(){ //加一层闭包,i以局部变量形式传递给内层函数
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    (function(){
    var temp = i; //调用局部变量
    ps[i].onclick = function(){
    console.log(temp);
    }
    })()
    }
    }
    function init(){ //加一层闭包,返回一个函数作为响应事件
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    ps[i].onclick = function(arg){
    return function(){
    console.log(arg)
    }
    }(i)
    }
    }
    function init(){
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    ps[i].onclick = new Function("console.log("+i+")")
    }
    }

    //错误的写法:
    function init(){
    var ps = document.getElementsByTagName('p');
    for(var i=0;i<ps.length;i++){
    ps[i].onclick = function(){
    console.log(i);//这里会输出5,不管点击那个都会输出5.
    }
    }
    }

    15、js 基本数据类型和引用数据类型

    基本数据类型 和 引用数据类型:
    ECMAScript 包括两个不同类型的值:基本数据类型和引用数据类型。
    常见的基本数据类型:
    number ,string ,boolean ,undefined,null。基本数据类型是按值访问的,因为可可以直接操作保存在变量中的实际值。

    引用数据类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置,如对象,数组,函数等。
    传值与传址:基本类型与引用类型最大的区别实际就是传值与传址的区别。
    例如:var a = [1,2,3,4];
    var b = a;//这个是传址,对象中传给变量的数据是引用类型,会存储在堆中。
    var c = a[0];//这个是传值,把对象中的属性/数组中的数组项赋值给变量,这时变量c是基本数据类型,存储在栈内存中,改变栈中的数据不会影响堆中的数据。
    浅拷贝:在定义一个对象或数组时,变量存放的往往只是一个地址。当我们使用对象拷贝时,如果属性是对象或数组时,这时候我们传递的也只是一个地址。因此子对象在访问属性时,会根据地址回溯到父对象
    指向的堆内存中,即父子对象发生了关联,两者的属性值会指向同一内存空间。

    深拷贝:不希望父子对象之间产生关联,那么可以使用深拷贝。

    16、JS原型链

    创建对象的方法:
    1. var obj1 = {name:'one'}; 字面量
    var obj11 = new Object({name:'one11'});

    2. var M = function(name){ this.name = 'two';} 构造函数
    var obj22 = new M('obj22');

    3. var P = {name:'three'}; Object.create
    var obj33 = Object.create(P);
    原型与原型链
    
    

     什么原型对象?实例?构造函数?

       var M = function(name){ this.name = name;}

       var o3 = new M('o3');

       实例就是对象,在上面这例子中,o3就是实例,M就是构造函数。实例通过new一个构造函数生成的。从上图中可以知道,实例的__protpo__指向的是原型对象。实例的构造函数的prototype也是指向的原型对象。原型对象的constructor指向的是构造函数。

    原型链:就是原型组成的链,对象的__proto__它的是原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,这样可以一直通过__proto__向上找,这就是原型链,找到最大的object,就终止。

    原型对象和实例之间有什么作用?

        var M = function(name){ this.name = name;}

        var o3 = new M('0s');

        var o5 = new M();

        o3.__proto__.say = function(){

           console.log('hello world')

        }

        o3.say();//hello world

        o5.say();//hello world

        只有函数有prototype,对象是没有的。但是函数也是有__proto__的,因为函数也是对象。函数的__proto__指向的是Function.prototype。

    
    

     instanceof 是判断实例对象的__proto__和生成该实例的构造函数的prototype是不是引用的同一个地址。是返回true,否则返回false。实例额原型构造函数,obj.__proto__.constructor

     new 运算符原理: 一个新对象被创建,他继承自foo.prototype.构造函数返回一个对象。在执行的时候,相应的传参会被传入,同时上下文this会被指定为这个新的实例。

         new foo 等同于new foo(),只能用在不传递任何参数的情况。

     

    17、js冒泡排序

    function sort (temp){
    for(var i=0;i<temp.length;i++){
    for(var j=0;j<temp.length-i-1;j++){
    if(temp[j]>temp[i]){
    var result = temp[j];
    temp[j] = temp[j+1];
    temp[j+1] = result;
    }
    }
    console.log(temp)
    }
    }
    var tempArray = [1,6,2,65,9,4,3,8,6];
    sort(tempArray); // 比较相邻的元素,如果后一个比前一个大,则交换位置。
    //快速排序:
    function quickSort(temp){
    if(temp.length<=1){
    return temp;
    }
    var index = Math.floor(temp.length/2);
    var pivot = temp.splice(index,1)[0];//获取删除的数字
    var arrleft = [];
    var arrright = [];
    for(var i=0;i<temp.length;i++){
    if(temp[i]<privot){
    arrleft.push(temp[i]);
    }else{
    arrright.push(temp[i]);
    }
    }
    return quickSort(arrleft).concat([pivot],quickSort(arrright));
    }

    18、es6函数新增

    函数形参的默认值:
    function foo(x,y='tom'){
    console.log(x,y)
    }
    foo('hello');//hello tom
    foo('hello','');//hello
    默认值与结垢赋值结合:
    function foo({x,y=3}){
    console.log(x,y);
    }
    foo({});//undefined 3;
    foo({x:1,y=2});//1,2
    foo();//报错
    参数默认值的位置:
    函数的length属性和作用域:
    length:指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。
    作用域:一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。
    rest参数: rest参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
    function foo(...values){
    var sum = 0;
    for(var val of values){
    sum+=val;
    }
    }
    foo(1,2,3);//6
    箭头函数: =>定义函数 (函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。不可以当作构造函数,也就是说不可以使用new命令。不可以使用arguments对象。不可以使用yield命令。)
    var f = () =>5;
    var sum = (nums,num2)=>num1+num2;

    19、同步异步

    同步异步定义:
    同步和异步关注的是消息通信机制。同步,就是调用某个东西时,调用方得等待这个调用返回结果才能继续往后执行。异步,和同步相反,调用方不会立即得到结果,而是在调用发出后调用者可以继续执行后续操作,被
    调用者通过状态来通知调用者,或者通过回调函数来处理这个调用。
    同步操作好比排队。

    20、发送http请求发生了什么?

    当我们在浏览器的地址输入 www.baidu.com 然后回车,回车这一瞬间发生了什么呢?
    
    

     域名解析---发起TCP 3次握手--建立TCP连接后发起http请求--服务器端响应http请求,浏览器得到html代码--浏览器解析html代码,并请求html代码中的资源--浏览器对页面进行渲染呈现给用户。

    21、文本超出部分显示省略号    

    /*css  单行*/
      .类名 {
         overflow:hidden;
         text-overflow:ellipsis;
         white-space:nowrap;
      }
    
    /*多行*/
       .类名 {
         display:-webkit-box;
         -webkit-box-orient:vertical;
         -webkit-line-clamp:3;/*这里显示几行文字*/
         overflow:hidden
       }

  • 相关阅读:
    二分图的部分关系
    二分图的部分关系
    日常训练赛 Problem C – Complete Naebbirac’s sequence
    日常训练赛 Problem C – Complete Naebbirac’s sequence
    J
    J
    Python strip()方法
    Python startswith()方法
    Python splitlines()方法
    Python split()方法
  • 原文地址:https://www.cnblogs.com/sunnyeve/p/11493213.html
Copyright © 2011-2022 走看看