美文网首页
js基础面试题

js基础面试题

作者: 阿拉斯加南海岸线 | 来源:发表于2022-09-08 18:15 被阅读0次

    面试题:延迟加载JS有哪些方式?

    延迟加载:async、defer
            例如:<script defer type="text/javascript" src='script.js'></script>
            
    defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本。
    async : async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)。
    

    面试题:JS数据类型有哪些?

    基本类型:string、number、boolean、undefined、null、symbol、bigint
    引用类型:object
    
    NaN是一个数值类型,但是不是一个具体的数字。
    

    面试题:JS数据类型考题

    考题一:
    console.log( true + 1 );                //2
    console.log( 'name'+true );             //nametrue
    console.log( undefined + 1 );       //NaN
    console.log( typeof undefined ); //undefined
    
    考题二:
    console.log( typeof(NaN) );       //number
    console.log( typeof(null) );      //object
    

    面试题:null和undefined的区别

    1. 作者在设计js的都是先设计的null(为什么设计了null:最初设计js的时候借鉴了java的语言)
    2. null会被隐式转换成0,很不容易发现错误。
    3. 先有null后有undefined,出来undefined是为了填补之前的坑。
    
    具体区别:JavaScript的最初版本是这样区分的:null是一个表示"无"的对象(空对象指针),转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
    

    面试题:==和===有什么不同?

    ==  :  比较的是值
            
            string == number || boolean || number ....都会隐式转换
            通过valueOf转换(valueOf() 方法通常由 JavaScript 在后台自动调用,并不显式地出现在代码中。)
    
    === : 除了比较值,还比较类型
    

    面试题:JS微任务和宏任务

    1. js是单线程的语言。
    2. js代码执行流程:同步执行完==》事件循环
        同步的任务都执行完了,才会执行事件循环的内容
        进入事件循环:请求、定时器、事件....
    3. 事件循环中包含:【微任务、宏任务】
    微任务:promise.then
    宏任务:setTimeout、setInterval
    
    要执行宏任务的前提是清空了所有的微任务
    
    流程:同步==》事件循环【微任务和宏任务】==》微任务==》宏任务=》微任务...
    微任务>dom渲染>宏任务
    

    面试题:JS作用域考题

    1. 除了函数外,js是没有块级作用域。
    2. 作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量。
         注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。
    3. 注意声明变量是用var还是没有写(window.)
    4. 注意:js有变量提升的机制【变量悬挂声明】
    5. 优先级:声明变量 > 声明普通函数 > 参数 > 变量提升
    

    面试的时候怎么看:

    1. 本层作用域有没有此变量【注意变量提升】
    2. 注意:js除了函数外没有块级作用域
    3. 普通声明函数是不看写函数的时候顺序
    
    考题一:
    function c(){
        var b = 1;
        function a(){
            console.log( b );
            var b = 2;
            console.log( b );
        }
        a();
        console.log( b );
    }
    c();
    
    考题二:
    var name = 'a';
    (function(){
        if( typeof name == 'undefined' ){
            var name = 'b';
            console.log('111'+name);
        }else{
            console.log('222'+name);
        }
    })()
    
    考题三:
    function fun( a ){
        var a = 10;
        function a(){}
        console.log( a );
    }
    fun( 100 );
    

    面试题:JS对象考题

    JS对象注意点:

    1. 对象是通过new操作符构建出来的,所以对象之间不想等(除了引用外);
    2. 对象注意:引用类型(共同一个地址);
    3. 对象的key都是字符串类型;
    4. 对象如何找属性|方法;
        查找规则:先在对象本身找 ===> 构造函数中找 ===> 对象原型中找 ===> 构造函数原型中找 ===> 对象上一层原型查找
    
    考题一:
     [1,2,3] === [1,2,3]   //false
    
    考题二:
    var obj1 = {
        a:'hellow'
    }
    var obj2 = obj1;
    obj2.a = 'world';
    console.log(obj1);  //{a:world}
    (function(){
        console.log(a);     //undefined
        var a = 1;
    })();
    
    考题三:
    var a = {}
    var b = {
        key:'a'
    }
    var c = {
        key:'c'
    }
    
    a[b] = '123';
    a[c] = '456';
    
    console.log( a[b] ); // 456
    

    面试题:JS作用域+this指向+原型的考题

    考题一:
    function Foo(){
        getName = function(){console.log(1)} //注意是全局的window.
        return this;
    }
    
    Foo.getName = function(){console.log(2)}
    Foo.prototype.getName = function(){console.log(3)}
    var getName = function(){console.log(4)}
    function getName(){
        console.log(5)
    }
    
    Foo.getName();    //2
    getName();        //4
    Foo().getName();  //1
    getName();        //1
    new Foo().getName();//3
    
    考题二:
    var o = {
        a:10,
        b:{
            a:2,
            fn:function(){
                console.log( this.a ); // 2
                console.log( this );   //代表b对象
            }
        }
    }
    o.b.fn();
    
    考题三:
    window.name = 'ByteDance';
    function A(){
        this.name = 123;
    }
    A.prototype.getA = function(){
        console.log( this );
        return this.name + 1;
    }
    let a = new A();
    let funcA = a.getA;
    funcA();  //this代表window
    
    考题四:
    var length = 10;
    function fn(){
        return this.length + 1;
    }
    var obj = {
        length:5,
        test1:function(){
            return fn();
        }
    }
    obj.test2 = fn;
    console.log( obj.test1() );                             //1
    console.log( fn()===obj.test2() );              //false
    console.log( obj.test1() == obj.test2() ); //false
    

    面试题:JS判断变量是不是数组,你能写出哪些方法?

    方式一:isArray
    var arr = [1,2,3];
    console.log( Array.isArray( arr ) );
    
    方式二:instanceof 【可写,可不写】
    var arr = [1,2,3];
    console.log( arr instanceof Array );
    
    方式三:原型prototype
    var arr = [1,2,3];
    console.log( Object.prototype.toString.call(arr).indexOf('Array') > -1 );
    

    方式四:isPrototypeOf()

    var arr = [1,2,3];
    console.log(  Array.prototype.isPrototypeOf(arr) )
    

    方式五:constructor

    var arr = [1,2,3];
    console.log(  arr.constructor.toString().indexOf('Array') > -1 )
    

    面试题:slice是干嘛的、splice是否会改变原数组

    1. slice是来截取的
        参数可以写slice(3)、slice(1,3)、slice(-3)
        返回的是一个新的数组
    2. splice 功能有:插入、删除、替换
        返回:删除的元素
        该方法会改变原数组
    

    面试题:JS数组去重

    方式一:new set
    var arr1 = [1,2,3,2,4,1];
    function unique(arr){
        return [...new Set(arr)]
    }
    console.log(  unique(arr1) );
    
    方式二:indexOf
    var arr2 = [1,2,3,2,4,1];
    function unique( arr ){
        var brr = [];
        for( var i=0;i<arr.length;i++){
            if(  brr.indexOf(arr[i]) == -1 ){
                brr.push( arr[i] );
            }
        }
        return brr;
    }
    console.log( unique(arr2) );
    
    方式三:sort
    var arr3 = [1,2,3,2,4,1];
    function unique( arr ){
        arr = arr.sort();
        var brr = [];
        for(var i=0;i<arr.length;i++){
            if( arr[i] !== arr[i-1]){
                brr.push( arr[i] );
            }
        }
        return brr;
    }
    console.log( unique(arr3) );
    

    面试题:找出多维数组最大值

    function fnArr(arr){
        var newArr = [];
        arr.forEach((item,index)=>{
            newArr.push( Math.max(...item)  )
        })
        return newArr;
    }
    console.log(fnArr([
        [4,5,1,3],
        [13,27,18,26],
        [32,35,37,39],
        [1000,1001,857,1]
    ]));
    

    面试题:给字符串新增方法实现功能

    面试题:给字符串新增方法实现功能

    给字符串对象定义一个addPrefix函数,当传入一个字符串str时,它会返回新的带有指定前缀的字符串,例如:

    console.log( 'world'.addPrefix('hello') ) 控制台会输出helloworld

    解答:
    String.prototype.addPrefix = function(str){
        return str  + this;
    }
    console.log( 'world'.addPrefix('hello') )
    

    面试题:找出字符串出现最多次数的字符以及次数

    var str = 'aaabbbbbccddddddddddx';
    var obj = {};
    for(var i=0;i<str.length;i++){
        var char = str.charAt(i);
        if( obj[char] ){
            obj[char]++;
        }else{
            obj[char] = 1;
        }
    }
    console.log( obj );
    //统计出来最大值
    var max = 0;
    for( var key in obj ){
        if( max < obj[key] ){
            max = obj[key];
        }
    }
    //拿最大值去对比
    for( var key in obj ){
        if( obj[key] == max ){
            console.log('最多的字符是'+key);
            console.log('出现的次数是'+max);
        }
    }
    

    面试题:new操作符具体做了什么

    1. 创建了一个空的对象
    2. 将空对象的原型,指向于构造函数的原型
    3. 将空对象作为构造函数的上下文(改变this指向)
    4. 对构造函数有返回值的处理判断
    
    function Fun( age,name ){
        this.age = age;
        this.name = name;
    }
    function create( fn , ...args ){
        //1. 创建了一个空的对象
        var obj = {}; //var obj = Object.create({})
        //2. 将空对象的原型,指向于构造函数的原型
        Object.setPrototypeOf(obj,fn.prototype);
        //3. 将空对象作为构造函数的上下文(改变this指向)
        var result = fn.apply(obj,args);
        //4. 对构造函数有返回值的处理判断
        return result instanceof Object ? result : obj;
    }
    console.log( create(Fun,18,'张三')   )
    

    面试题:闭包

    1. 闭包是什么
        闭包是一个函数加上到创建函数的作用域的连接,闭包“关闭”了函数的自由变量。
    2. 闭包可以解决什么问题【闭包的优点】
        2.1 内部函数可以访问到外部函数的局部变量
        2.2 闭包可以解决的问题
                var lis = document.getElementsByTagName('li');
          for(var i=0;i<lis.length;i++){
            (function(i){
              lis[i].onclick = function(){
                alert(i);
              }
            })(i)
          }
    3. 闭包的缺点
        3.1 变量会驻留在内存中,造成内存损耗问题。
                    解决:把闭包的函数设置为null
      3.2 内存泄漏【ie】 ==> 可说可不说,如果说一定要提到ie
    

    面试题:原型链

    1. 原型可以解决什么问题
        对象共享属性和共享方法
    2. 谁有原型
    函数拥有:prototype
    对象拥有:__proto__
    3. 对象查找属性或者方法的顺序
        先在对象本身查找 --> 构造函数中查找 --> 对象的原型 --> 构造函数的原型中 --> 当前原型的原型中查找
    4. 原型链
        4.1 是什么?:就是把原型串联起来
        4.2 原型链的最顶端是null
    

    面试题: JS继承有哪些方式

    方式一:ES6
    class Parent{
        constructor(){
            this.age = 18;
        }
    }
    
    class Child extends Parent{
        constructor(){
            super();
            this.name = '张三';
        }
    }
    let o1 = new Child();
    console.log( o1,o1.name,o1.age );
    
    方式二:原型链继承
    function Parent(){
        this.age = 20;
    }
    function Child(){
        this.name = '张三'
    }
    Child.prototype = new Parent();
    let o2 = new Child();
    console.log( o2,o2.name,o2.age );
    
    方式三:借用构造函数继承
    function Parent(){
        this.age = 22;
    }
    function Child(){
        this.name = '张三'
        Parent.call(this);
    }
    let o3 = new Child();
    console.log( o3,o3.name,o3.age );
    
    方式四:组合式继承
    function Parent(){
        this.age = 100;
    }
    function Child(){
        Parent.call(this);
        this.name = '张三'
    }
    Child.prototype = new Parent();
    let o4 = new Child();
    console.log( o4,o4.name,o4.age );
    

    面试题:工厂函数和构造函数的区别

    一、工厂函数
    使用工厂函数创建对象,外部不关心内部是怎么实现的,只需要传入正确的参数,就可以声明对象

    工厂函数
    如上,工厂函数,主要解决了代码冗余,封装成了函数,统一处理。
    总共有三步:1. 创建对象 2. 对象赋值 3. 返回对象
    优点:只需要传入一个正确的参数,就可以获取你所需要的对象,而无需知道其创建细节
    缺点
    1、工厂函数的职责相对过重,增加新的feature,需要修改工厂类的判断逻辑,违背了开闭原则(当程序需要变化时,尽量通过扩展程序来实现修改。而不是修改现有代码来实现变化);
    2、创建的对象与工厂函数的prototype之间没有原型上的关联;
    工厂函数2
    一、构造函数
    将工厂函数的例子进行改造
    构造函数

    可以观察到,构造函数,使用了this,并且使用了new 来实例化对象。 并没有像工厂函数,声明对象,返回对象。因为new,为我们做了这些操作。
    创建自定义函数,可以通过prototype与 构造函数做关联,这是构造函数和工厂函数最大的不同

    面试题:说一下call、apply、bind区别

    共同点:功能一致
    可以改变this指向
    
    语法: 函数.call()、函数.apply()、函数.bind()
    
    区别:
    1. call、apply可以立即执行。bind不会立即执行,因为bind返回的是一个函数需要加入()执行。
    2. 参数不同:apply第二个参数是数组。call和bind有多个参数需要挨个写。
    
    场景:
    1. 用apply的情况
    var arr1 = [1,2,4,5,7,3,321];
    console.log( Math.max.apply(null,arr1) )
    
    2. 用bind的情况
    var btn = document.getElementById('btn');
    var h1s = document.getElementById('h1s');
    btn.onclick = function(){
        console.log( this.id );
    }.bind(h1s)
    

    面试题:sort背后原理是什么?

    V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。
    
    之前的版本是:插入排序和快排,现在是冒泡
    
    原理实现链接:https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js
    
    ***710行代码开始***
    

    面试题:深拷贝和浅拷贝

    共同点:复制
    
    1. 浅拷贝:只复制引用,而未复制真正的值。
    var arr1 = ['a','b','c','d'];
    var arr2 = arr1;
    
    var obj1 = {a:1,b:2}
    var obj2 = Object.assign(obj1);
    
    2. 深拷贝:是复制真正的值 (不同引用)
    var obj3 = {
        a:1,
        b:2
    }
    var obj4 = JSON.parse(JSON.stringify( obj3 ));
    
    //递归的形式
    function copyObj( obj ){
        if(  Array.isArray(obj)  ){
            var newObj = [];
        }else{
            var newObj = {};
        }
        for( var key in obj ){
            if( typeof obj[key] == 'object' ){
                newObj[key] = copyObj(obj[key]);
            }else{
                newObj[key] = obj[key];
            }
        }
        return newObj;
    }
    console.log(  copyObj(obj5)  );
    

    面试题:localStorage、sessionStorage、cookie的区别

    公共点:在客户端存放数据
    区别:
    1. 数据存放有效期
            sessionStorage : 仅在当前浏览器窗口关闭之前有效。【关闭浏览器就没了】
            localStorage   : 始终有效,窗口或者浏览器关闭也一直保存,所以叫持久化存储。
            cookie               : 只在设置的cookie过期时间之前有效,即使窗口或者浏览器关闭也有效。
    2. localStorage、sessionStorage不可以设置过期时间
         cookie 有过期时间,可以设置过期(把时间调整到之前的时间,就过期了)
    3. 存储大小的限制
        cookie存储量不能超过4k
        localStorage、sessionStorage不能超过5M
        
        ****根据不同的浏览器存储的大小是不同的。
    

    2.1 ES6面试题

    面试题:var、let、const区别

    var、let、const 共同点都是可以声明变量的
    
    区别一:
        var 具有变量提升的机制
        let和const没有变量提升的机制
    区别二:
        var 可以多次声明同一个变量
        let和const不可以多次声明同一个变量
    区别三:
        var、let声明变量的
        const声明常量
        
        var和let声明的变量可以再次赋值,但是const不可以再次赋值了。
    区别四:
        var声明的变量没有自身作用域
        let和const声明的变量有自身的作用域
    

    面试题:作用域考题

    考题一:let和const没有变量提升性

    console.log( str );//undefined
    var str = '你好';
    
    console.log( num );//报错
    let num = 10;
    

    考题二:

    function demo(){
        var n = 2;
        if( true ){
            var n = 1;
        }
        console.log( n );//1
    }
    demo();
    
    
    function demo(){
        let n = 2;
        if( true ){
            let n = 1;
        }
        console.log( n );//2
    }
    demo();
    

    考题三:可以修改

    const obj = {
        a:1
    }
    obj.a = 11111;
    console.log( obj )
    
    const arr = ['a','b','c'];
    arr[0]= 'aaaaa';
    console.log( arr );
    

    面试题:将下列对象进行合并

    方式一:Object.assign

    const a = {a:1,b:4};
    const b = {b:2,c:3};
    
    let obj1 = Object.assign(a,b);
    console.log( obj1 );
    

    方式二:...

    let obj2 = {...a,...b};
    console.log( obj2 );
    

    方式三:自己封装方法

    function extend( target,  source ){
        for(var key in source){
            target[key] = source[key];
        }
        return target;
    }
    console.log( extend(a,b) );
    

    面试题:箭头函数和普通函数有什么区别?

    1. this指向的问题
        箭头函数中的this只在箭头函数定义时就决定的,而且不可修改的(call、apply、bind)
        ****箭头函数的this指向定义时候、外层第一个普通函数的this
    2. 箭头函数不能new(不能当作构造函数)
    3. 箭头函数prototype
    4. 箭头函数arguments
    

    面试题:Promise有几种状态

    有三种状态:
    pending(进行中)
    fulfilled(已成功)
    rejected(已失败)
    

    面试题:find和filter的区别

    区别一:返回的内容不同
        filter 返回是新数组
        find   返回具体的内容
    区别二:
        find :匹配到第一个即返回
        filter : 返回整体(没一个匹配到的都返回)
    

    面试题:some和every的区别

    some  ==》 如果有一项匹配则返回true
    every ==》 全部匹配才会返回true
    

    相关文章

      网友评论

          本文标题:js基础面试题

          本文链接:https://www.haomeiwen.com/subject/srmonrtx.html