javaScript基础

JS基础

1、typeof运算符和instanceof运算符以及isPrototypeof()方法的区别

typeof是一个运算符,用于检测数据的类型,比如基本数据类型number、string、boolean、null、undefined、以及引用数据类型object、function,但是对于正则表达式、日期、数组这些引用数据类型,它会全部识别为object;
instanceof同样也是一个运算符,它就能很好识别数据具体是哪一种引用类型。它与isPrototypeOf的区别就是它是用来检测构造函数的原型是否存在于指定对象的原型链当中;而isPrototypeOf是用来检测调用此方法的对象是否存在于指定对象的原型链中,所以本质上就是检测目标不同。

2、基本数据类型和引用数据类型

基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。
  引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数组是对象,函数是对象,正则表达式是对象)

3、描述以下变量的区别:null undefined

null:是 JavaScript 的关键字,用于描述“空值”,对其执行 typeof 操作,返回“object”,即为一个特殊的对象值,可以表示数字、字符串和对象是“无值”的。
undefined:是预定义的全局变量,其值为“未定义”,它是变量的一种取值,表示变量没有初始化。当查询对象属性、数组元素的值时,如果返回 undefined则表示属性或者元素不存在;如果函数没有任何返回值,也返回 undefined。
需要注意的是,虽然 null 和 undfined 是不同的,但是因为都表示“值的空缺”,两者可以互换。因此,使用“==”认为二者是相等的,需要使用“===”来区分它们。

4、Object.is()与原来的比较操作符“=”、“”的区别

两等号判等,会在比较时进行类型转换。 三等号判等(判断严格),比较时不进行隐式类型转换,(类型不同则会返回false)。
Object.is 在三等号判等的基础上特别处理了 NaN 、-0 和 +0 ,保证 -0 和 +0 不再相同,但 Object.is(NaN, NaN) 会返回 true.
Object.is 应被认为有其特殊的用途,而不能用它认为它比其它的相等对比更宽松或严格。

5、什么是事件代理/事件委托

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

6、什么是事件冒泡?什么是事件捕获

事件冒泡:就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的

7、如何阻止冒泡

只需在函数中添加阻止冒泡事件函数e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来阻止事件的冒泡传播;

8、如何阻止默认事件

只需用JS的preventDefault()函数

9、Get和post的区别

Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。 2. Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。 3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。 4. Get执行效率却比Post方法好。Get是form提交的默认方法。

10、简述JavaScript中this的指向

纯粹的作为函数调用:全局函数中,this指向window;
作为对象方法的调用:当函数被作为某个对象的方法调用时,this就是那个对象;
作为构造函数调用:this指向新对象;
apply、call调用:this指向改变后的调用这个函数的对象。

11、解释下为什么接下来这段代码不是IIFE(立即调用的函数表达式):

function foo(){
//code
}()
IIFE的表示是将函数包含在一个括号内,变成为一个表达式,随后跟着一个(),就立即执行这个函数了,修改成如下形式:

(function fn(){…})()
1
IIFE(立即调用的函数表达式)的作用
● 创建作用域,内部保存一些大量临时变量的代码,防止命名冲突
● 一些库的外层用这种形式包起来,防止作用域污染
● 运行一些只执行一次的代码

12、请解释变量声明提升

hoisting机制:javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。
知识点一:javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构
知识点二:变量声明宣称一个名字的存在,变量定义则为这个名字分配存储空间,而变量初始化则是为名字分配的存储空间赋初值
知识点三:javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
1、语言内置:所有的作用域中都有 this 和 arguments 关键字
2、形式参数:函数的参数在函数作用域中都是有效的
3、函数声明:形如function foo() {}
4、变量声明:形如var bar;
知识点四:1、函数参数是原始类型的值(数值、字符串、布尔值),传递方式是传值传递,即在函数体内修改参数值,不会影响到函数外部。
2、函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递,传入的是原始值的地址,因此在函数内部修改参数,将会影响到原始值。
注意,如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值!

13、请指出document.onload和documen.ready两个事件的区别

ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件);
onload,指示页面包含图片等文件在内的所有元素都加载完成。

14、JavaScript里arguments究竟是什么

在js中万物皆对象,甚至数组字符串函数都是对象。所以这个叫做arguments的东西也是个对象,而且是一个特殊的对象,它的属性名是按照传入参数的序列来的,第1个参数的属性名是’0’,第2个参数的属性名是’1’,以此类推,并且它还有length属性,存储的是当前传入函数参数的个数,很多时候我们把这种对象叫做类数组对象。类数组对象和数组都是对象这个妈生的,但是数组是大哥比类数组对象多了很多其他的玩具(方法),类数组对象只是长得很像数组的弟弟而已。

15、请解释一下JavaScript的同源策略

同源策略是客户端脚本(尤其是Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。)只能读取来自同一来源的窗口和文档的属性。

16、什么是跨域?有什么方法解决跨域带来的问题

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
【1】设置document.domain解决无法读取非同源网页的 Cookie问题
因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)
【2】跨文档通信 API:window.postMessage()
调用postMessage方法实现父窗口http://test1.com向子窗口http://test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)
它可用于解决以下方面的问题:
页面和其打开的新窗口的数据传递
多窗口之间消息传递
页面与嵌套的iframe消息传递
上面三个场景的跨域数据传递
【3】JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个script元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
【4】CORS
CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
(1)、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
(2)、带cookie跨域请求:前后端都需要进行设置
【前端设置】根据xhr.withCredentials字段判断是否带有cookie

17、什么是闭包?使用场景是?

闭包就是能够读取其他函数内部变量的函数,说白了闭包就是个函数,只不过是处于其他函数内部而已。
由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

18、Call()和apply()的区别

apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
它们的共同之处:
都“可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。
它们的不同之处:
apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。
call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,那么 Global 对象被用作thisObj。
实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。

19、请你谈谈cookie的弊端(localstorage、sessionstorage)

a. 每个特定的域名下最多生成的cookie个数有限制
b. IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie
c. cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节
d. 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。
e. 扩展:浏览器本地存储
在HTML5中提供了sessionStorage和localStorage。
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁,是会话级别的存储
localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的

20、什么是函数柯里化

柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果。
思想就是将原本需要三个参数才能运行的函数,转化为,可以先让一个函数去接受一个参数,调用后,再返回去调用剩余其他的参数,直到完成所有参数的调用。
柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)©。
柯里化不会调用函数。它只是对函数进行转换。
柯里化 是一种转换,将 f(a,b,c) 转换为可以被以 f(a)(b)© 的形式进行调用。JavaScript 实现通常都保持该函数可以被正常调用,并且如果参数数量不足,则返回偏函数。
柯里化让我们能够更容易地获取偏函数。就像我们在日志记录示例中看到的那样,普通函数 log(date, importance, message) 在被柯里化之后,当我们调用它的时候传入一个参数(如 log(date))或两个参数(log(date, importance))时,它会返回偏函数。

21、数组中的forEach和map的区别

共同点:
都是循环遍历数组中的每一项
每一次执行匿名函数都支持三个参数,数组中的当前项item,当前项的索引index,原始数组input
匿名函数中的this都是指window
只能遍历数组
不同点:
forEach()没有返回值!!!!
参数:value数组中的当前项,index当前项的索引,array原始数组;
数组中有几项,那么传递进去的匿名回调函数就需要执行几次
理论上这个方式是没有返回值的,只是遍历数组中的每一项,不对原来数组进行修改,但是可以自己通过数组的索引来修改原来的数组
map()有返回值,可以return出来!!!!
参数:value数组中的当前项,index当前项的索引,array原始数组
区别:map的回调函数中支持return返回值,return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆了一份,把克隆这一份的数组中的对应项改变了 );

22、什么是JS事件循环event loop

主线程运行的时候,产生堆和栈,栈中的代码调用各种外部API,异步操作执行完成后,就在消息队列中排队。只要栈中的代码执行完毕,主线程就会去读取消息队列,依次执行那些异步任务所对应的回调函数

eventloop
  详细步骤如下:
  1、所有同步任务都在主线程上执行,形成一个执行栈
  2、主线程之外,还存在一个"消息队列"。只要异步操作执行完成,就到消息队列中排队
  3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取消息队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
  4、主线程不断重复上面的第三步
【循环】
  从代码执行顺序的角度来看,程序最开始是按代码顺序执行代码的,遇到同步任务,立刻执行;遇到异步任务,则只是调用异步函数发起异步请求。此时,异步任务开始执行异步操作,执行完成后到消息队列中排队。程序按照代码顺序执行完毕后,查询消息队列中是否有等待的消息。如果有,则按照次序从消息队列中把消息放到执行栈中执行。执行完毕后,再从消息队列中获取消息,再执行,不断重复。
  由于主线程不断的重复获得消息、执行消息、再取消息、再执行。所以,这种机制被称为事件循环

23、JS如何处理防抖和节流

函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下图,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件。
当持续触发scroll事件时,事件处理函数handle只在停止滚动1000毫秒之后才会调用一次,也就是说在持续触发scroll事件的过程中,事件处理函数handle一直没有执行。
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。如下图,持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数。
函数节流主要有两种实现方法:时间戳和定时器。接下来分别用两种方法实现throttle~
(时间戳)当高频事件触发时,第一次会立即执行(给scroll事件绑定函数与真正触发事件的间隔一般大于delay,如果你非要在网页加载1000毫秒以内就去滚动网页的话,我也没办法o(╥﹏╥)o),而后再怎么频繁地触发事件,也都是每delay时间才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了 (最后一次触发事件与倒数第二次触发事件的间隔小于delay,为什么小于呢?因为大于就不叫高频了呀(╹▽╹))。
当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到delay时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在delay秒后才执行。而后再怎么频繁触发事件,也都是每delay时间才执行一次。当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。
节流中用时间戳或定时器都是可以的。更精确地,可以用时间戳+定时器,当第一次触发事件时马上执行事件处理函数,最后一次触发事件后也还会执行一次事件处理函数。

24、JS里垃圾回收机制是什么,常用的是哪种,怎么处理的?

JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
JS中最常见的垃圾回收方式是标记清除。
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
工作流程:
1.垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。
2.去掉环境中的变量以及被环境中的变量引用的变量的标记。
3.再被加上标记的会被视为准备删除的变量。
4.垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。

25、什么是虚拟DOM

文档对象模型或 DOM 定义了一个接口,该接口允许 JavaScript 之类的语言访问和操作 HTML 文档。元素由树中的节点表示,并且接口允许我们操纵它们。但是此接口需要付出代价,大量非常频繁的 DOM 操作会使页面速度变慢。

Vue 通过在内存中实现文档结构的虚拟表示来解决此问题,其中虚拟节点(VNode)表示 DOM 树中的节点。当需要操纵时,可以在虚拟 DOM的 内存中执行计算和操作,而不是在真实 DOM 上进行操纵。这自然会更快,并且允许虚拟 DOM 算法计算出最优化的方式来更新实际 DOM 结构。

一旦计算出,就将其应用于实际的 DOM 树,这就提高了性能,这就是为什么基于虚拟 DOM 的框架(例如 Vue 和 React)如此突出的原因。

一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?

(1)查找浏览器缓存 (2)本地host没有的话然后DNS 解析、查找该域名对应的 IP 地址、重定向(301)、发出第二个 GET 请求 (3)进行 HTTP 协议会话 (4)客户端发送报头(请求报头) (5)服务器回馈报头(响应报头) (6)html 文档开始下载 (7)文档树建立,根据标记请求所需指定 MIME 类型的文件 (8)文件显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值