javaScript总结(1-32)

一、说说JavaScript中的数据类型?区别?

小结:js中基本数据类型包括string,number,boolean,null,undefined,symbol,bigint,引用数据类型object,简单数据类型在内存中是通过栈区存储变量和值的,而引用数据类型是在栈区存储变量和存储地址,实际数据存储在堆区。

二、Javscript数组的常用方法有哪些?

小结:数组常用方法,增push、unshift、splice、concat,删pop,shift,splice,slice,改splice,查includes,indexOf,find,排序方法sort,reverse,转换方法join,迭代方法,forEach,filter,map,every,some

三、Javascript字符串的常用方法有哪些?

小结:字符串常用方法,增:字符串拼接 + ,模版字符串 ,concat,删:slice,subString,改trim,trimLeft,trimRight,toLowerCase(),查chatAt,indexOf,includes,转换方法:split,模版匹配方法match,search,replace

四、谈谈 Javascript 中的类型转换机制

小结:类型转换包括显示转换和隐式转换
显示转换就是我们通过方法对值进行转换,常见方法:Number(),paserInt(),String(),Boolean()
隐式转换就是js进行的自动转换,例如使用比较运算符时会转换为Boolean,使用算数运算符(+,-,*,/,%)时会转换为Number,特殊情况,字符串使用 + 时会拼接

五、== 和 === 区别,分别在什么情况使用?

小结:相等操作符()会做类型转换,再进行值的比较,全等运算符不会做类型转换。
null 和 undefined 比较,相等操作符(
)为true,全等为false
除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符(),其他情况建议一律使用全等操作符(=)

六、深拷贝浅拷贝的区别?如何实现一个深拷贝?

小结:浅拷贝对基本数据类型可以精确拷贝,对引用数据类型拷贝的只是内存地址,所以当我们在修改对象中的属性时,会将原始对象的数据也发生改变。而深拷贝可以创建一个一模一样的新对象来存储数据,在修改对象数据时不会对原始数据做出改变。浅拷贝通常在使用Object中的assign方法,Array的是splic和concat方法以及拓展运算符复制时出现,进行深拷贝可以通过lodash中的clonedeep方法,jQuery的etend方法,JSON.stringify()以及自写一个循环深拷贝方法。

七、说说你对闭包的理解?闭包使用场景?

小结:闭包就是一个函数和其周围状态的引用捆绑在一起,使用闭包可以使我们在内层函数访问外层函数的作用域,使用场景有创建私有变量、函数柯里化、模拟私有方法、防抖和节流等

八、说说你对Javascript中作用域的理解?

小结:作用域就是变量或函数能被访问的区域或集合,一般分为全局作用域、函数作用域和块级作用域,全局作用域就是不在函数或大括号中的作用域,在全局作用域声明的变量可以在程序任何位置访问,函数作用域在声明的函数中,在函数中声明的变量只能在函数内部访问,块级作用域中由es6引入的let,const声明的变量只能在块级作用域中访问,
作用域链
在js中使用变量时,js引擎会先尝试在当前作用域寻找、如果没找到会到上层作用域中寻找,以此类推直到找到或访问到全局作用域,如果还未找到(在非严格模式下会隐式声明该变量)或直接报错。

九、JavaScript原型,原型链 ? 有什么特点?

小结:在js中创建一个函数时,就会生成一个属性prototype,该属性就是此函数的原型对象,在该对象中有个属性为constructor,用来指向该函数,这样原型对象和它的函数就联系了起来,通过这个函数创造出来的所有实例的原型__proto__就是该原型对象。
原型链就是,我们在创造出来的实例中可以访问它的构造函数的原型对象中的方法,当我们访问某个属性或方法时,他会先在自己构造函数的原型对象prototype上寻找,如果没找到,就继续向该原型对象的原型__proto__中寻找,这样一层一层向上查找形成的链式结构就称为原型链
原型链的尽头是构造函数function Object的原型对象,在该原型对象中的__proto__指行null,所以原型链的尽头为null

十、说说Javascript中的继承?如何实现继承?

小结:继承就是通过子类通过该方式具有调用父类的各种属性和方法,而不用重复编写相同的代码,子类继承父类的同时还应该可以重新定义某些方法,即覆盖父类的方法,使其获得和父类不同的功能。
继承的方法有原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。
拓展问题:
简单说一说:原型链继承
原型链继承就是将子构造函数的原型对象prototype指向父构造函数的实例,这样子构造函数的实例就可以访问父构造函数原型对象上的方法和属性,缺点就是子修改属性或方法时父的方法或属性也发生改变。
简单说一说:构造函数继承
构造函数继承就是通过在子构造函数中调用父构造函数,并通过call、apply将this指向为子构造函数的实例。
缺点就是无法调用父构造函数的原型对象中的方法
简单说一说:组合继承
组合继承就是将原型链继承和构造函数继承综合起来,先将子构造函数的原型对象指向父构造函数的实例,再在子构造函数中调用父构造函数并将this指向子构造函数的实例,这样互补了原型链继承和构造函数继承的缺点,但是调用了两次父构造函数,多了一次调用开销。
简单说一说:原型式继承
原型式继承就是通过Object.create方法进行继承,缺点就是该方法是一个浅拷贝,多个实例的引用类型属性指向相同的内存,存在篡改可能。
简单说一说:寄生式继承
寄生式继承是指创建一个新对象,并在该对象上增加一些父类的属性和方法,然后返回该对象。这种方式的缺点与原型式继承相同。
简单说一说:寄生组合式继承
寄生组合式继承是指使用“借用构造函数”继承父类实例的属性和方法,并将子类原型指向一个父类实例的副本。这种方式可以避免调用两次父类构造函数,且不会继承父类原型上的属性和方法。
简单说一说:类的继承
ES6 中,可以使用 class 和 extends 关键字来实现继承。即定一个父类(也称为基类)和一个子类(也称为派生类),并通过 extends 关键字让子类继承父类的属性和方法。
我们通过babel转码工具不难发现,extends本质上也是寄生组合继承。

十一、说说你对Javascript中this对象的理解

小结:this是在函数运行时自动创建的一个内部对象,只能在函数内部使用,在函数运行时一旦确定,就不能在更改。
this默认绑定在不同环境,不同严格模式下的指向都不同,在浏览器默认指向window,node默认指向global,严格模式下默认绑定nudefined
在对象中的方法会隐式绑定为上以及对象
使用new关键字时会绑定为实例对象
当然我们也可以通过call,apply,bind对this的指向进行修改。
es6中的箭头函数中的this在书写就会确定,编译时会绑定。

十二、JavaScript中执行上下文和执行栈是什么?

小结:执行上下文时javascript代码运行的抽象概念,只要代码在运行,那他一定在执行上下文的过程中,一般分为全局执行上下文、函数执行上下文、eval函数执行上下文,生命周期一般包括创建阶段-执行阶段-回收阶段。创建阶段会确定this指向,执行阶段会进行变量赋值、代码运行等操作,回收阶段就会等待回收执行上下文。
执行栈就是在创建执行上下文时会压入执行栈中,先压入全局执行上下文,调用函数就会压入该函数执行上下文,以此类推,因为执行栈拥有后进先出的结构,所以当全局执行上下文被压出栈时,程序结束。

十三、JavaScript中的事件模型如何理解?

小结:说到事件模型就得先知道事件和事件流,js中的事件就是点击事件、加载事件等,因为dom是个树形结构,所以在处理事件时就会出现一个顺序问题,这就引出了事件流,它包括事件捕获阶段、事件处理阶段、事件冒泡阶段。
而js的事件模型包括
原始事件模型,属于dom0级事件,onclick\onblur等,直接绑定,特点就是绑定快
标准事件模型,属于dom2级事件,addeventlistener,从document先捕获以此检查是否绑定监听函数,如果有则执行,再处理事件触发目标元素的监听函数,再冒泡至document依此检查是否有事件监听函数,如果有则执行。
特点是可以绑定多个事件处理器,互不冲突。
ie事件模型,事件到达目标函数执行监听函数,再冒泡到document,依次检查经过节点是否绑定事件监听,如果有则执行

十四、说说 typeof 与 instanceof 区别?

小结:typeof是用来检测数据类型的·,返回值是监测数据的类型,其中在检测null的类型时会返回Object,而null本质是基本数据类型,这是因为javascript在存储数据时是使用二进制存储,在判定是否为Object时是查看前三位是否是0,而null存储的全是0,所以null被判定为Object,
instanceof是用来检测构造函数的prototype的某个属性是否在某个实例的原型链上,函数左侧时实例对象,右侧是目标属性,返回值时true或false,通过new关键字创建的实例可以通过instanceof判断该实例是否是某构造函数创造的。
相同点:都是判断数据类型的方法
不同的:typeof返回的是数据类型,instanceof返回的是布尔值。
instanceof可以准确判断数据类型但是不能正确判断基础数据类型,而typeof在判断null是会返回Object,并且复杂类型只有function会返回function,其他都会返回Object。
解决方法:使用Object.prototype.toString,调用该方法会返回[Object Xxx]格式的字符串。

十五、解释下什么是事件代理?应用场景?

小结:事件代理通俗来讲就是将一个元素的事件函数绑定或委托到另一个元素上,因为事件流包括捕获-目标-冒泡三个阶段,我们将同一类的处理函数绑定到他们的父层或更高层元素上,当事件响应到目标函数时会通过冒泡机制触发到外层绑定的事件上。应用场景一般在列表标签上ul-li,可以将li的点击事件委托给ul,具体例子有导航栏。

十六、说说new操作符具体都干了什么?

小结:new是用来通过构造函数创建实例对象的,通过new创建的实例对象,可以调用该构造函数的属性以及其原型链上的属性。new操作流程第一步,先创建一个新对象,第二步,将该对象的原型指向构造函数的原型对象,第三步,将构造函数的this绑定给创建的新对象,第四步,判断返回值如果返回值是原始值,则返回原始值,如果返回值是对象,则返回新对象。

十七、Ajax 原理是什么?如何实现?

小结:Ajax全称Async javascript and xml 即异步的javascript和xml,简单来说就是通过xmlHttpRequest发起网络请求,从服务器获取数据,通过javascript操作DOM渲染数据。操作流程为1、先初始化XmlHttpRequest实例,、通过实例的open方法携带发送方法method、路径url、是否异步async等参数,3、通过实例的send方法发送出去,send可以携带请求参数,如果是get请求send参数为空。4、通过onreadystatuschange监听请求状态,如果状态为4表示请求发送完成,我们可以对不同的请求返回状态码进行操作处理。5、最后将处理结果更新到页面。

十八、bind、call、apply 区别?如何实现一个bind?

小结:call,apply,bind都是用来改变this指向的,但是他们之间也有些不同,
call第一个参数是this指向,后面的是参数列表。这个函数使用后会立即调用一次,并且修改的this指向是临时的。
apply第一个参数也是this指向,第二个参数是函数接收的参数,以数组的形式传入,修改后会立即调用一次,并且修改的this指向也是临时的。
bind第一个参数同样是this的指向,后面的参数是函数的参数列表,不会立即调用,而是会返回一个永久更改this指向的新函数。

十九、说说你对JavaScript中事件循环的理解​

小结:事件循环,在javascript设计之初就是单线程(因为js多用来操作dom,如果是多线程一个删除dom一个添加dom,浏览器就无法处理),也就是说在程序运行中同一时间只允许有一个任务进行,如果有耗时任务的话就会运行缓慢,为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种运行机制,这种机制就叫做事件循环。它包括同步任务和异步任务,异步任务又分为宏任务和微任务,宏任务例如script(外层同步代码),setTimeout等,微任务包括Premise.then等。

二十、说说你对正则表达式的理解?应用场景?

小结:正则表达式通常原来校验字符串格式是否符合定义的规则,常用来表单校验,手机号、身份证号等,经常使用的方法有test、repalce、match、exec等

二十一、说说你对DOM的理解,常见的操作有哪些?

小结:DOM全称document object model
文档对象模型,是html和xml文档的编程接口,他提供了对文档结构化的表述。并定义了一种方式可以对文档的结构样式和内容进行改变。
dom常见操作有创建节点,增,删,改,查节点,创建:createElement,createTextNode,createAttribute,
增:innerHtml,appendChild 删:remobeChild
改:innerHtml,innerText,innerContent
查:也叫获取节点,querySelector,querySelectorAll,getElementById,getElementByTagName,getElementByClassName

二十二、 说说你对BOM的理解,常见的BOM对象你了解哪些?

小结:BOM全称browser object model
浏览器对象模型,是浏览器与内容交互的对象。其作用就是跟浏览器做一些交互效果,例如页面的前进、后退,刷新、浏览器窗口变化,滚动条的滚动以及一些浏览器信息,浏览器版本等

二十三、举例说明你对尾递归的理解,有哪些应用场景

小结:尾递归就是在函数尾部调用自己的方式,相较于普通尾调的基础上,多了两个特征,一个是调用的是自己,另一个是仅计算占用常量栈空间。普通递归和调用其他函数一样,都会为函数创建一个新的栈帧,压入调用栈中,而尾递归中,当前语句是最后一条待执行语句,于是调用返回时栈帧中并没有其他事情可做,因此就没有保存栈帧的必要了,而是通过覆盖当前栈帧而不是在重新添加,这样所使用的栈空间就会大大缩减,效率就会大大提高。

二十四、说说 JavaScript 中内存泄漏的几种情况?

小结:内存泄漏就是程序运行中,由于疏忽或错误造成未能释放不再使用的内存。这种现象就叫做内存泄漏。
出现这种现象的原因是因为垃圾回收机制中使用的是引用计数法,在程序运行过程中,使用的数据会打上标记,当引用次数为0时,就表示这个值用不到了,这个值就会被释放,但是有时会出现不在使用某些值,但引用次数却不为0,这时内存就不会被释放。
出现情况:
1.意外的全局变量。函数中未使用let,var,const定义变量,这个值会作为全局变量定义,引用次数为1,但全局中不使用它。
2.函数中用this创建变量。
3.定时器

二十五、JavaScript中本地存储的方式有哪些?区别及应用场景?

小结:cookie 小型文本文件,不超过4kb,由name和value还有其他几个用于控制有效期,安全性,使用范围的可选属性组成。
localStorage 本地持久化存储,自己不删除,永久存在,存储的大小与浏览器厂商有关,一般5M。
sessionStorage使用方法与localStorage使用方法相似,唯一不同的是生命周期,当页面一关闭,数据会自动删除
indexedDB用于存储大量结构化数据
区别
存储大小:cookie只有4kb,sessionStorage和localStorage 5M甚至更大,与浏览器厂家有关
有效时间:cookie可以自己设置过期时间,sessionStorage在关闭会话或浏览器时自动删除,localStorage永久保存
数据与服务器交互方式:cookie可以自动传入服务器,服务器也可以写数据到客户端
sessionStorage和localStorage不会自动发送数据。
使用场景:cookie:标记用户或跟踪用户行为
sessionStorage:敏感账号登录
localStorage:长期保存的本地令牌

二十六、JavaScript中如何实现函数缓存?有哪些应用场景?

小结:函数缓存就是将函数的结果进行缓存,本质就是用空间换时间。js中实现函数缓存主要依靠闭包,科里化,高阶函数。
实现方法:
1、在当前函数作用域定义了一个空对象,用于缓存运行结果
2、运用柯里化返回一个函数,返回的函数由于闭包特性,可以访问到cache
3、然后判断输入参数是不是在cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache中
应用场景:
1、对于昂贵的函数调用,执行负载计算的函数。
2、对于具有重复输入值的递归函数。
3、对于有限且高度重复输入范围的函数。
4、对于纯函数,即每次使用特定输入返回相同输出的函数。

二十七、说说 JavaScript 数字精度丢失的问题,解决方案?

小结:首先我们可以想一个问题1/3 = 0.333333这一个无限循环小数,在计算机存储中是不可能将这个无限循环小数的全部存在内存中。而是使用近似值表示,这就出现了精度丢失问题。在js中使用的是双精度浮点数编码,简单来说就是使用科学计数法来表示这些数,使用8个字节,64比特,1位符号位,11位指数位,52位尾数位。这就限制了能存储为位数,也限制了精度253 , 最大数21023,超过这个数就会变成Infinity。
解决方案:理论上用有限的空间来存储无限的小数是不可能保证精确的,但我们可以处理一下得到我们期望的结果
具体方法就是通过parseFloat和toPrecision对数据进行操作
还可以使用第三方库math.js BigDecimal.js

二十八、说说函数节流和防抖?有什么区别?如何实现?

小结:
节流是n秒内只运行一次,在n秒内重复触发将不执行。
防抖是n秒后执行一次,在n秒内重复触发将取消上次触发的,执行本次触发的,以此类推,直至最后一次触发。
区别:
相同点:都可以使用定时器setTimeout实现
目的都是降低执行频率,节省计算资源。
不同点:在一段连续操作后(总操作时间远大于n,相邻操作时间小于n),防抖每n秒触发一次,节流只执行最后一次。
应用场景:
防抖:输入账号或密码等需要校验提示的表单元素,输入完成后进行校验
输入搜索框内容,输入完成进行搜索
调整窗口大小,调整完成后进行计算页面元素宽度,防止重复渲染
节流:滚动加载,每过一段时间查看距离底部的距离,等距离少于多少进行加载下一页数据
搜索框,搜索联想功能

二十九、JavaScript如何判断一个元素是否在可视区域中?

小结:
1.offectTop,scrollTop
2.getBoundingClinentRect
3.Intersection Observer交叉观察器

应用场景:无限滚动,图片懒加载,广告曝光度,根据是否在可视区域决定动画或任务是否执行。

三十、JavaScript如何实现上拉加载,下拉刷新?

小结:1.用现成的js库,isscroll,better-scroll,pulltorefresh.js等
2.写一个上拉加载
我们需要三个值,可视窗口区域高度clientHeight,视窗到window顶部的距离scrollTop,页面的总高度scrollHeight,思路就是通过计算可视区域距离页面底部小于某个值时进行刷新,使用scrollHeight - scrollTop - clientHeight 计算结果就是距离底部的距离。
3.写一个下拉刷新
监听touchstart事件,记录初始位置的值,e.touches[0].pageY
监听touchmove事件,监听当前位置与初始位置差值,并使用translateY向下偏移相同距离
监听touchend事件,如果滑动达到最大值,触发callback执行刷新操作,并将translateY设为0

三十一、什么是单点登录?如何实现?

小结:单点登录就是通过一次登录后,一段时间内可以访问多个系统无需再次登录。
实现方法:
同域名:
同域名下可以通过cookie实现,cookie的domin属性设置为父域名,path设置为根路径,再将session ID或Token保存在父域名,在该域名下的子域名都可以访问这个cookie来判断是否登录。
不同域名:不同域名cookie是不共享的
方法一:部署一个认证中心,用户如果在应用系统中为未登录(无token)状态就会执行跳转至认证中心,如果认证中心也为未登录状态,就会返回登录页,等待用户登录。如果认证中心为登录状态,用户就无需再次登录,而是生成一个token拼接在url回传应用系统,应用系统拿到token先回向认证中心确认token合法性,合法就会将token写入cookie。
方法二:登录成功后,将session ID或token保存在本地,通过一些手段将他写入其他域下的localStorage中。

三十二、web常见的攻击方式有哪些?如何防御?

小结:1.xss跨站脚本攻击,通过将恶意代码植入页面中。一般通过评论,表单,私信等输入框拼接恶意代码。
预防:对输入的’<‘,’>'等特殊字符进行重新编码(&lt,&gt)
2.CSRF跨站请求伪造,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。
受害者登录过网站,拥有请求凭证,攻击者因此可以绕过注册凭证。
预防:
阻止不明外域的访问
同源检测
Samesite Cookie
提交时要求附加本域才能获取的信息
CSRF Token
3.Sql 注入攻击,是通过将恶意的 Sql查询或添加语句插入到应用的输入参数中,再在后台 Sql服务器上解析执行进行的攻击
预防方式如下:
严格检查输入变量的类型和格式
过滤和转义特殊字符
对访问数据库的Web应用程序采用Web应用防火墙

参考:https://github.com/febobo/web-interview

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
to-array-buffer 是一个 JavaScript 方法,用于将特定类型的数据转换为 ArrayBuffer 对象。 ArrayBuffer 是一种用于存储二进制数据的固定长度缓冲区。它提供了一种将数据存储在内存中的方式,可以通过其索引访问和操作数据。 to-array-buffer 方法是将数据转换为 ArrayBuffer 的常见方式之一。它接受一个数据源作为参数,并返回一个与数据长度相匹配的 ArrayBuffer 对象。 下面是一个使用 to-array-buffer 的示例: ```javascript const data = [1, 2, 3, 4, 5]; // 输入的数据 const buffer = new ArrayBuffer(data.length * 4); // 根据数据长度创建一个 ArrayBuffer 对象,每个元素占用 4 个字节 const view = new DataView(buffer); // 创建一个用于操作 ArrayBuffer 的 DataView 对象 for (let i = 0; i < data.length; i++) { view.setInt32(i * 4, data[i], true); // 将每个数据元素写入到 ArrayBuffer 中,每个元素占用 4 个字节 } console.log(buffer); // 打印输出 ArrayBuffer 对象 ``` 上述代码中,我们首先创建了一个包含一组整数的数据源。然后我们根据数据源的长度创建了一个与之相匹配的 ArrayBuffer 对象。接下来,我们使用一个 DataView 对象来操作这个 ArrayBuffer。通过一个循环,我们将数据源中的每个元素写入到 ArrayBuffer 中。最后,我们输出了 ArrayBuffer 对象。 总结来说,to-array-buffer 方法是将特定类型的数据转换为 ArrayBuffer 的方法之一。它可以帮助我们将 JavaScript 中的数据转换为二进制数据,并方便地进行操作和传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值