WEB前端高频面试题(三)—— JS八股文

简介: WEB前端高频面试题(三)—— JS八股文

玻璃晴朗,橘子辉煌。

——北岛《过节》

原文:”一位本地英雄 ,在废弃的停车场上 ,唱歌 ,玻璃晴朗 ,桔子辉煌 。”

释义:他在一个废弃的停车场上唱着歌,如同玻璃透明而明朗,如同橘子一般青涩而辉煌。

JavaScript基础面试题

       JavaScript在Web前端开发中扮演着重要的角色,它是实现网页交互性和动态性的关键技术。掌握JavaScript对于成为一名成功的前端开发人员来说是至关重要的。

       理解JavaScript语言的核心概念、语法和特性。这样,在面试中被问到相关问题时,便能够更自信地回答。

延迟加载JS有哪些方式(async、defer)?

延迟加载: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..

 

要执行宏任务的前提是清空了所有的微任务

 

流程:同步==》事件循环【微任务和宏任务】==》微任务==》宏任务=》微任务...

 

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 );

说一下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月前
|
并行计算 前端开发 JavaScript
Web Worker:让前端飞起来的隐形引擎
在现代 Web 开发中,前端性能优化是一个至关重要的课题,尤其是对于计算密集型的应用,如图像处理、视频处理、大规模数据分析等任务。单线程的 JavaScript 引擎常常成为性能瓶颈,导致应用变得迟缓。Web Worker,作为一种强大的技术,使得前端能够在后台进行并行计算,从而实现高效的任务处理,不影响主线程的运行和用户的交互体验。
317 108
|
2月前
|
JavaScript 前端开发 Java
前端框架选择之争:jQuery与Vue在现代Web开发中的真实地位-优雅草卓伊凡
前端框架选择之争:jQuery与Vue在现代Web开发中的真实地位-优雅草卓伊凡
295 72
前端框架选择之争:jQuery与Vue在现代Web开发中的真实地位-优雅草卓伊凡
|
4月前
|
移动开发 前端开发 JavaScript
前端web创建命令
本项目使用 Vite 搭建 Vue + TypeScript 开发环境,并基于 HTML5 Boilerplate 提供基础模板,快速启动现代前端开发。
46 2
|
4月前
|
Web App开发 编解码 移动开发
零基础音视频入门:你所不知道的Web前端音视频知识
本文回顾了Web端音视频的发展历程,同时还介绍了视频的编码、帧率、比特率等概念,提到了Canvas作为视频播放的替代方案,以及FFmpeg在音视频处理中的重要作用等知识。
102 1
|
8月前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
198 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
11月前
|
前端开发 JavaScript 搜索推荐
HTML与CSS在Web组件化中的核心作用及前端技术趋势
本文探讨了HTML与CSS在Web组件化中的核心作用及前端技术趋势。从结构定义、语义化到样式封装与布局控制,两者不仅提升了代码复用率和可维护性,还通过响应式设计、动态样式等技术增强了用户体验。面对兼容性、代码复杂度等挑战,文章提出了相应的解决策略,强调了持续创新的重要性,旨在构建高效、灵活的Web应用。
210 6
|
5月前
|
Web App开发 前端开发 JavaScript
鸿蒙5开发宝藏案例分享---Web适配一多开发实践
这是一份实用的鸿蒙Web多设备适配开发指南,针对开发者在不同屏幕尺寸下的布局难题提供了解决方案。文章通过三大法宝(相对单位、媒体查询和窗口监听)详细介绍如何实现智能适配,并提供了多个实战案例,如宫格布局、对话框变形和自适应轮播图等。此外,还分享了调试技巧及工具推荐,帮助开发者快速上手并优化性能。最后鼓励读者实践探索,并提示更多官方资源等待发现。
|
12月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
622 3
|
7月前
|
关系型数据库 MySQL 数据库
基于Flink CDC 开发,支持Web-UI的实时KingBase 连接器,三大模式无缝切换,效率翻倍!
TIS 是一款基于Web-UI的开源大数据集成工具,通过与人大金仓Kingbase的深度整合,提供高效、灵活的实时数据集成方案。它支持增量数据监听和实时写入,兼容MySQL、PostgreSQL和Oracle模式,无需编写复杂脚本,操作简单直观,特别适合非专业开发人员使用。TIS率先实现了Kingbase CDC连接器的整合,成为业界首个开箱即用的Kingbase CDC数据同步解决方案,助力企业数字化转型。
1209 5
基于Flink CDC 开发,支持Web-UI的实时KingBase 连接器,三大模式无缝切换,效率翻倍!
|
7月前
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。