前端面试题(JavaScript篇)

介绍javaScript的基本数据类型?

基本数据类型:Number数值、String字符串、 Boolean 布尔、Null空值、underfined未定义

object是javaScript中所有对象的父对象

数据封装类对象:object、Array、Boolean、Number、String

其他对象:Function、Arguments、Math、Date、Error、RegExp

其他数据类型:Symbol

引用数据类型:Object(Array,Date,RegExp,Function)

js的内置对象有哪些?

js常用的对象有:Arguments 函数参数集合     Array 数组     Boolean 布尔对象  Data 日期时间  Error 异常对象     Function 函数构造器     Math 数学对象    Number数值对象  Object  基础对象RegExp 正则表达式对象   String字符串对象

js创建对象的方法有几种?

工厂方式,构造函数方式,原型模式,混合构造函数原型模式,动态原型方式

创建函数的几种方法?

函数声明  function fun(){ }

函数表达式  let fun =function(){ }

函数对象式  let fun = new function(“参数”,“函数体”)

数组怎样转换成 json对象,再转化回去?

javascript 的 typeof 返回哪些数据类型

object number function boolean underfind string

js的延迟加载的方式有几种?

六种:defer属性、async属性、动态创建dom方式、使用jquery的getScript方法、使用setTimeout延迟方法、让js最后加载。

HTML 5为 <script>标签定义了async属性。添加此属性后,脚本和HTML将一并加载(异步),代码将顺利运行。

浏览器遇到async脚本时不会阻塞页面渲染,而是直接下载然后运行。但这样的问题是,不同脚本运行次序就无法控制,只是脚本不会阻止剩余页面的显示。

async属性只适用于外部脚本文件。

把 Script 标签 放在页面的最底部的 body 封闭之前 和封闭之后有什么区 别?

浏览器会如何解析它们? 如果说放在 body 的封闭之前,将会阻塞其他资源的加载 如果放在 body 封闭之后,不会影响 body 内元素的加载

split() join() 的区别

前者是切割成数组的形式, 后者是将数组转换成字符串

join() 方法: 用于把数组中的所有元素放入一个字符串。

元素是通过指定的分隔符进行分隔的。

split()方法:用于把一个字符串分割成字符串数组。

数组方法 pop() push() unshift() shift()

Push()尾部添加 pop()尾部删除 Unshift()头部添加 shift()头部删除

什么是闭包?

js闭包就是一个函数内嵌套着一个函数,子函数引用了外部函数的变量,当子函数被return出去调用时,变量会一直保持在内存中。

怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

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

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

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

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

appendChild() //添加 removeChild() //移除 replaceChild() //替换 insertBefore() //插入

3)查找

getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的 Name 属性的值 getElementById() //通过元素 Id,唯一性

Javascript 如何实现继承?

原型链继承,借用构造函数继承,组合继承,寄生式继承,寄生组合继承

请你谈谈 Cookie 的弊端?

缺点: 1.`Cookie`数量和长度的限制。每个 domain 最多只能有 20 条 cookie,每个 cookie 长度不 能超过 4KB,否则会被截掉。

2.安全性问题。如果 cookie 被人拦截了,那人就可以取得所有的 session 信息。即使加密 也与事无补,因为拦截者并不需要知道 cookie 的意义,他只要原样转发 cookie 就可以达到 目的了。

3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存 一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

JavaScript this 指针、闭包、作用域

this:指向调用上下文

闭包:内层作用域可以访问外层作用域的变量

作用域:定义一个函数就开辟了一个局部作用域,整个 js 执行环境有一个全局作用域

 new操作符具体干了什么呢?
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
 2、属性和方法被加入到 this 引用的对象中。
 3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
防抖与节流
防抖
    在滚动事件中需要做个复杂计算或者实现一个按钮的防二次点击操作。可以通过函数防抖动来实现

 节流
    防抖动和节流本质是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行

js的同源策略
同源:协议相同,域名相同,端口相同
 不同源:只要协议、域名、端口其中之一不同,不同源就会产生跨域
 同源策略主要作用:限制不同源的服务器相互访问,提高浏览器访问网页的安全性

什么是事件代理?
即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。
事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能
可以大量节省内存占用,减少事件注册
可以实现当新增子对象时无需再次对其绑定

 数组中的forEach 和map 的区别?
forEach 和 map 的相同点
相同点 都是循环遍历数组中的每一项

forEach 和 map 方法里每次执行匿名函数都支持 3 个参数,参数分别是 item(当前每一项)
,index(索引值),arr(原数组)
匿名函数中的 this 都是指向 window 只能遍历数组 都不会改变原数组 

 区别
 map方法
1.map 方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值
2.map 方法不会对空数组进行检测,map 方法不会改变原始数组。
3.浏览器支持:chrome、Safari1.5+、opera 都支持,IE9+, 若 arr 为空数组,
则 map 方法返回的也是一个空数组。

 forEach 方法
1.forEach  方法用来调用数组的每个元素,将元素传给回调函数
2.forEach 对于空数组是不会调用回调函数的。 无论 arr 是不是空数组,
forEach 返回的都是    undefined。这个方法只是将数组中的每一项作为 callback 的参数执行一次

 JS 里垃圾回收机制是什么,常用的是哪种,怎么处理的?
JS  的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着
垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。

JS 中最常见的垃圾回收方式是
 标记清除
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,
则将其标记为“离开环境”。标记“离开环境”的就回收内存

 工作流程:
垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记 去掉环境中的变量
以及被环境中的变量引用的变量的标记再被加上标记的会被视为准备删除的变量
垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间

js的几种遍历循环方式
forEach():参数为回调函数,会遍历数组所有的项,回调函数接受三个参数,分别为value,index,self;forEach没有返回值    
 map():同forEach,同时回调函数返回数据,组成新数组由map返回    
 every():同forEach,同时回调函数返回布尔值,全部为true,由every返回true    
 some():同forEach,同时回调函数返回布尔值,只要由一个为true,由some返回true

iframe 的优缺点?

优点: 1. 解决加载缓慢的第三方内容如图标和广告等的加载问题

2. Security sandbox

3. 并行加载脚本

缺点: 1. iframe 会阻塞主页面的 Onload 事件

2. 即时内容为空,加载也需要时间

3. 没有语意

 字符串函数:
                .charAt(index);//charAt() 方法可返回指定位置的字符。
                .charCodeAt(index);//方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。
                String.fromCharCode();//方法返回由指定的 UTF-16 代码单元序列创建的字符串
                .indexOf();
                .lastIndexOf();
                .concat();
                .split();//把字符串分割为数组  split("")
                .slice();
                .substring();
                .substr();//新版本废弃 推荐 substring
  
                .replace(searchValue,replaceStr|function);//文本替换 替换匹配的第一个字符 返回新字符串
                .replaceAll(searchValue,replaceStr|function);//文本替换 替换匹配到所有字符
                .toLowerCase();//把英文字符全部转为小写
                .toUpperCase();//把英文字符串全部转为大写
                .repeat();//复制指定次数的字符
                .trim();// 去除首尾空格.
    数组函数:
                indexOf();  检索项在数组里面第一次出现的位置 没有返回-1
                push(); 往数组末尾添加一项或多项
                pop(); 删除数组最后一项 并返回删除项
                shift(); 删除数据第一项 并返回删除项
                unshift(); 往数组开头插入一项或多项
                sort();  排序数组里面的元素.
                slice(); 获取数组片段并返回 不改变原数组
                splice(); 截取 ,删除 ,修改数组项,并返回受影响结果. 会改变原数组
                concat(); 合并数组
                join(); 把数组里面每项用 分隔符连接成字符串
                reverse(); 翻转数组
                map();     遍历数组每一项并返回一个新数组
                filter();  过滤数组
                forEach(); 遍历数组

call,apply,bind区别
call(this指向的对象, 参数1, 参数2, 参数3, ...)
apply(this指向的对象, [参数1, 参数2, 参数3, ...])
bind(this指向的对象, 参数1, 参数2, 参数3, ...)
相同点:
call,apply,bind都是函数原型的方法,
都是改变函数调用时内部this的指向,
第一个参数都是函数内部this指向的对象
不同点:
call从第二个参数开始为函数的参数,而且参数是单一传递,不能以参数数组传递;
apply从第二个参数开始为函数的参数,而且第二个参数为数组,
该数组包含函数的所有参数
 bind从第二个参数开始为函数的参数,而且参数是单一传递,不能以参数数组传递,
并且返回一个绑定函数内部this指向的函数

使用箭头函数应注意什么?
(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)
(2)不能够使用arguments对象
(3)不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数

什么是对象的浅拷贝和深拷贝,有何区别,简述如何实现对象的深拷贝

浅拷贝拷贝的是对象的引用的地址

深拷贝是通过递归遍历对象,直到值为基本数据类型再拷贝

浅拷贝新旧对象的值会相互影响。深拷贝不会相互影响

实现过程:定义一个deepcopy函数,接收一个参数,

使用typeof判断参数是否为object

接着使用Array.isArray判断是否为数组,是就生成空数组,否就生成空对象

将参数进行for in 循环,判断每一项是否为object,是则调用自身然后赋值给新对象,,否则之前赋值,把新对象return出去。

json..parse(Json.stringify(obj))也能进行对象和数组的深拷贝,但无法拷贝函数

猜你喜欢

转载自blog.csdn.net/H_hl2021/article/details/121751152