JavaScript相关:
js的构造函数里面有什么操作
- 立刻在堆内存中创建一个新的对象
- 将新建的对象设置为函数中的this
- 逐个执行函数中的代码
- 将新建的对象作为返回值
浮点数计算0.7+0.1,原因
不等于0.8,但近似于0.8.
因为JavaScript采用的是一种二进制表示法,来表示浮点数。由于舍入误差,二进制浮点数表示法并不能精确表示类似0.1这样简单的数字。
this的指向 哪几种
this指向的形式4种
a.如果是一般函数,this指向全局对象window;
b.在严格模式下"use strict",为undefined.
c.对象的方法里调用,this指向调用该方法的对象.
d.构造函数里的this,指向创建出来的实例.
改变this指向的方式
以下属于函数的方法
改变this的指向并且执行调用函数
.call(), call(thisScope, arg1, arg2, arg3…)
.apply(), apply(thisScope, [arg1, arg2, arg3…]);两个参数
而bind 改变this的指向,返回的是函数
.bind() , bind(thisScope, arg1, arg2, arg3…)
arguments
arguments是类数组对象,有length属性,不能调用数组方法
可用Array.from()转换
同步任务 异步任务
Js中的异步操作:
- setTimeOut
- setInterval
- ajax
- promise
- I/O
同步任务 or 异步任务
- 同步任务(synchronous):在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
- 异步任务(asynchronous):不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
宏任务 or 微任务
除了广义的同步任务和异步任务,我们对任务有更精细的定义:
- 宏任务(macro-task):整体代码script、setTimeOut、setInterval
- 微任务(mincro-task):promise.then、promise.nextTick(node)
事件循环的顺序,决定Js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。(event loop)
闭包 列举闭包的用处
闭包是指有权访问另外一个函数作用域中的变量的函数。
闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。当在一个函数内定义另外一个函数就会产生闭包。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
优点:1:变量长期驻扎在内存中;
2:避免全局变量的污染;
3:私有成员的存在 ;
缺点:
常驻内存 会增大内存的使用量 使用不当会造成内存泄露,详解:
js作用域
作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
作用域包含全局作用域、函数作用域、和es6中新增的块级作用域。
作用域链, 通俗地讲,当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
1.当执行函数时,总是先从函数内部找寻局部变量
2.如果内部找不到(函数的局部作用域没有),则会向创建函数的作用域(声明函数的作用域)寻找,依次向上.
promise的状态有那些
等待(pending)、已完成(fulfilled)、已拒绝(rejected)
Promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换.
JS 不是面向对象的解释 面向对象的特点
JavaScript并非“面向对象的语言”,而是“基于对象的语言”,这个说法一度流传甚广,而事实上,我至今遇到的持有这一说法的人中,无一能够回答“如何定义面向对象和基于对象”这个问题。
面向对象的三大特征
三大特征分别为:封装,继承和多态
封装: 我们平时所用的方法和类都是一种封装,当我们在项目开发中,遇到一段功能的代码在好多地方重复使用的时候,我们可以把他单独封装成一个功能的方法,这样在我们需要使用的地方直接调用就可以了。
继承: 继承在我们的项目开发中主要使用为子类继承父类
多态: 多态的具体表现为方法重载和方法重写
什么情况下内存会无法释放
js的垃圾回收机制就是为了防止内存泄漏的,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
https://www.cnblogs.com/xiaocuncheng/p/11101698.html
隐式转换的规则,对象的转换原理是什么?
-
[0] == [0]
为false
, 是因为两个数组的地址不一样 -
[0] == 0
为true
,[0]
会先转为原始值,即‘0’ == 0
-
{} == 0
会报错,是因为在浏览器的控制台上直接这样写的话,{}
被当作空代码块,而不是对象,最后执行实际上是== 0
,如果你写({} == 0)
则为false
。 -
-1 == false
false -
-1==true
相当于-1==1;当然是false有一个值是布尔值,一个是数字,先将布尔值转数字
https://www.cnblogs.com/chenmeng0818/p/5954215.html
如何保证表单安全
https://blog.csdn.net/weixin_33736832/article/details/88626737
事件委托和监听
事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的响应。
举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。
好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。
事件轮训机制
https://blog.csdn.net/fu983531588/article/details/90576803
前端路由
https://www.jianshu.com/p/5aab4a6711d5
变量提升
js和其他语言一样,都要经历编译和执行阶段。而js在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二步则是在执行阶段执行到该语句的时候才执行。
https://blog.csdn.net/qq_42606051/article/details/82016733
BOM与DOM,及BOM相关的一些属性
我们都知道, javascript
有三部分构成,ECMAScript
,DOM
和BOM
,根据宿主(浏览器)的不同,具体的表现形式也不尽相同,ie和其他的浏览器风格迥异。
- DOM 是 W3C 的标准; [所有浏览器公共遵守的标准]
- BOM 是 各个浏览器厂商根据 DOM
在各自浏览器上的实现;[表现为不同浏览器定义有差别,实现方式不同]- window 是 BOM 对象,而非 js 对象;
Window对象包含属性:document、location、navigator、screen、history、frames
https://www.cnblogs.com/xiaodaizi/p/9855713.html
https://www.jianshu.com/p/f3d63b4a7021
原型链,原型链原理
https://blog.csdn.net/weixin_46124214/article/details/104168455
数组方法 哪些返回新数组 哪些改变数组‘
https://blog.csdn.net/weixin_46124214/article/details/104334640
如何让事件先冒泡后捕获
在DOM标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获事件。
说一下什么是virtual dom
用JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异 把所记录的差异应用到所构建的真正的DOM树上,视图就更新了。
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。
暂停死区
在代码块内,使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”
addEventListener参数
addEventListener(event, function, useCapture)
其中,event指定事件名;function指定要事件触发时执行的函数;useCapture指定事件是否在捕获或冒泡阶段执行。
作用域不同sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;localStorage:在所有同源窗口都是共享的;cookie:也是在所有同源窗口中共享的
浏览器在生成页面的时候,会生成那两颗树?
构造两棵树,DOM树和CSSOM规则树
当浏览器接收到服务器相应来的HTML文档后,会遍历文档节点,生成DOM树,
CSSOM规则树由浏览器解析CSS文件生成,
js监听对象属性的改变
http://www.zhangchen915.com/index.php/archives/581/
能来讲讲JS的语言特性吗
运行在客户端浏览器上;
不用预编译,直接解析执行代码;
是弱类型语言,较为灵活;
与操作系统无关,跨平台的语言;
脚本语言、解释性语言。解释型语言的程序不需要在运行前编译,在运行程序的时候才翻译。
箭头函数与普通函数的区别在于:
- 箭头函数没有this,所以需要通过查找作用域链来确定this的值,这就意味着如果箭头函数被非箭头函数包含,this绑定的就是最近一层非箭头函数的this,
- 箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象
- 不能通过new关键字调用,同样也没有new.target值和原型
事件模型常用方法:
event.stopPropagation
:阻止捕获和冒泡阶段中,当前事件的进一步传播,
event.preventDefault
,取消该事件(假如事件是可取消的)而不停止事件的进一步传播,
event.target
:指向触发事件的元素,在事件冒泡过程中这个值不变
dom是什么
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM。
关于dom的api有什么
节点创建型api,页面修改型API,节点查询型API,节点关系型api,元素属性型api,元素样式型api等
基本数据类型和引用数据类型的区别
基本数据类型的值是不可变的,任何方法都无法改变一个基本类型的值,当这个变量重新赋值后看起来变量的值是改变了,但是这里变量名只是指向变量的一个指针,所以改变的是指针的指向改变,该变量是不变的,但是引用类型可以改变
基本数据类型不可以添加属性和方法,但是引用类型可以
基本数据类型的比较是值的比较,引用类型的比较是引用的比较,比较对象的内存地址是否相同
基本数据类型的特点:直接存储在栈(stack)中的数据
引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里.引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。
js加载过程阻塞,解决方法
HTML5 中,对script元素,新增了async属性和defer属性,它们的作用都是加快页面的加载速度,使脚本代码的读取不再妨碍页面上其他元素的加载。
在使用这两个属性时,在浏览器发出该脚本文件的请求,开始脚本文件的下载工作后,立即继续执行页面的加载工作。脚本文件下载完毕时会触发一个onload事件,我们可以通过监听该事件及指定事件处理函数来指定当脚本文件下载完毕时所需要执行的一些处理。
这两个属性的区别仅在于何时执行onload事件处理函数。
async
:脚本加载完毕后立即执行该事件处理函数,所以如果页面中使用多个外部脚本文件,且均为这些外部脚本使用async属性,则这些外部脚本的onload事件处理函数的执行顺序不与页面中执行外部脚本文件的引用顺序保持一致,一旦某个外部脚本文件下载完毕,立即执行该脚本的onload事件处理函数。
defer
:脚本文件加载完毕后,并不立即执行该脚本文件的onload事件处理函数,而是等到页面全部加载完毕后,才执行脚本文件的onload事件处理函数,则在页面加载完毕后按这些外部脚本的引用顺序来执行外部脚本的onload事件处理函数。
<script defer src = 'test.js' onload="myInit"></script>
<script async src = 'test.js' onload="myInit"></script>
Ajax解决浏览器缓存问题
禁止浏览器缓存功能有如下几种方法:
在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")
。
在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")
。
在URL后面加上一个随机数:"fresh=" + Math.random();
。
在URL后面加上时间搓:"nowtime=" + new Date().getTime();
。
如果是使用jQuery,直接这样就可以了$.ajaxSetup({cache:false})
。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录。
eval是做什么的
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
fetch发送2次请求的原因
fetch发送post请求的时候,总是发送2次,第一次状态码是204,第二次才成功?
原因很简单,因为你用fetch的post请求的时候,导致fetch 第一次发送了一个Options请求,询问服务器是否支持修改的请求头,如果服务器支持,则在第二次中发送真正的请求。
module.export
exports
export
的区别
在es5中,用module.exports
和exports
导出模块,用require
引入模块。
es6新增export
和export default
导出模块,import
导入模块。