JavaScript基本语法
001、浅谈堆和栈的理解?
js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引用数据类型的变量存储在堆中 引用类型数据的地址也存在栈中
当访问基础类型变量时,直接从栈中取值。当访问引用类型变量时,先从栈中读取地址,在根据地址到堆中取出数据
002、js中的数据类型分为哪几类
基本数据类型:number string undefined null boolean
引用数据类型:Object
003、js中的强制类型转换与隐式类型转换
隐式类型转换:== != - * / % *= /= -= %=
强制类型转换:Number parseInt():取整转换 parseFloat()
004、 javascript三大部分组成
1、ECMAscript====》它是一种规范 造一架汽车------》发动机 js的一种规范
2、BOM :browser Object Model===> 浏览器对象模型
3、DOM : document===> 文档对象模型
005、undefined 和null的区别?先记住看不懂的会讲的
null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
undefined:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
006、谈谈你对NaN的理解
a、Not a Number 不是一个数字
b、NaN仅仅代表不是一个数字,自身和自身都不相等(NaN != NaN)
c、如何判断NaN isNaN===>如果是NaN,返回true,否则返回false Number.isNaN( )
d、NaN的数据类型是number
007、说下i++与++i之间的区别
i++: 先使用,在加1
++i; 先加1,在使用
008、 javascript转换成false的值有哪些?
0 '' null undefined false
009、null 、 true false转换成数字的值都是多少
false如果转换成一个数字的话是0
true如果转换成一个数字的话就是1
null如果转换成一个数字的话就是0
010、javascript能够转换为true的值有哪些?
非0的数字 非空的字符串 true 非空的对象
011、if语句的优化
1、把次数多的条件和执行结果放到最前面
2、减少第一次无用的判断,可以用嵌套判断
3、判断语句禁止出现三次嵌套
012、谈谈你对switch的理解
1、switch的括号里面放的是一个变量
2、case相对应的值是关于这个变量的一个值
3、switch里面的这个变量和case里面这个变量不会进行隐式类型的一个转换,而是进行了恒等比较。所以一定要注意这个变量和这个case里面的值是不是一个类型
4、关于switch里面的case会有一个穿透效果,这个效果有的时候会给我们带来好处(详情请看最后一个案例),有的时候会给我们带来坏处,如果不需要这种穿透效果的时候加break
5、swicth里面如果这个变量没有匹配到case里面这个值,那么就需要返回一个信息。所以在case的末尾一定要加上一个default;这样既给用户的体验比较完美,另一方面对代码的今后维护也有很大的帮助
6、比较的值是固定值
013、if和swicth的应用场景
if :
1、具体的值进行判断
2、区间的判断
3、对运算的结果是boolean类型表达式进行判断 true false
switch:
1、对具体的值进行判断
2、值的个数是固定的
对于几个固定的值判断,建议使用switch 语句。因为switch 语句会将具体的答案都加载进内存,效率相对高一点
基于代码的可读性:如果条件较少时,if-else容易阅读,而条件较多时switch更容易阅读
014、目前所了解的转义字符
\"
\'
\n 表示换行
\t tab键
015、while需要注意的地方
1、初始化一个变量
2、while()括号里面是判断条件
3、除了在执行相应的代码以外还要在代码块中改变循环体的条件变量===》在{}里面改变
016、do-while循环的使用及while的区别
do-while() 无论条件是否成立至少执行一次,和while规则一样,唯一不同的是do{}while会先执行一次(先执行后判断
017、谈谈你对for循环的理解
for(第一个是:循环变量也是初始化变量;第二个是判断循环条件;第三个是改变循环变量){
....代码块
}
循环变量: 用于控制循环是否结束的变量(给变量赋初始值,只执行一次)
循环条件: 判断循环是否继续(每次都会执行)
改变循环变量:用于改变循环变量(每次都会执行)
018、while和for的区别
for循环是知道了循环次数,while是不知道循环次数
for限定了循环次数
while是条件循环
019、break和continue return的区别
continue:continue只是中止本次循环,接着开始下一次循环 ,只能出现在循环中
break:break用于完全结束一个循环,跳出循环体 不在执行break下面的代码,只能出现在选择或者循环中
return:返回函数的值,不在执行return下面的代码,只能出现函数中
020、让函数执行有哪几种方式
1、js是基于事件驱动的语言、因此可以通过js的事件来调用函数让函数执行
2、直接写函数名加()
3、立即执行函数。在字面量函数后面({}后面加())
021、定义函数的几种方式
1、关键字函数:function fnName(){};
2、字面量函数:var fn = function(){};
3、构造函数:var fn = new Function()
022、函数的作用
1、减少代码的编写(代码重复利用)
2、隐藏处理细节,便于今后的修改和维护
3、控制执行时机
023、谈谈你对参数的理解
1、参数分为:形参和实参
2、有了参数以后可以使函数变的更加灵活
3、形参和实参要一一对应
4、如果对应的形参没有传值,那么值是undefined
024、什么是作用域链?
1、简单说就是作用域集合 当前作用域 -> 父级作用域 -> ... -> 全局作用域 形成的作用域链条
全局作用域的变量和方法都可以进行调用
局部的变量和方法只能局部进行调用( 除闭包外 )
局部可以访问全局的变量和方法
025、console.log与console.dir的区别
console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息。
console.dir()可以显示一个对象所有的属性和方法。
026、谈谈你对arguments的了解
1、函数内部自带的一个对象
2、存储的是所有的实参
3、可以使用[]及下标访问arguments中的内容 arguments[0] 访问第一个实参
4、可以使用 arguments.length 确定传入实参的个数
5、最常用的用途: 判断传入参数的个数(根据参数个数做不同的事情)
027、请说一下js的编译和执行
1、js的预编译:
a、把var 和 function 定义的变量提升到script的最上方
b、赋值语句不会被提升,哪怕等号后面是一个function
2、js执行:代码从上往下执行
028、简单的阐述一下js的变量声明提升
变量声明和函数声明从他们代码中出现的位置被移动到执行环境的顶部,这个过程就叫做提升 只有声明操作会被提升,赋值和逻辑操作会被留在原地等待执行
Js编译器会把变量声明看成两个部分分别是声明操作(var a)和赋值操作(a=2)
背会!!!!递归与循环的区别
递归算法:
优点:代码简洁、清晰,并且容易验证正确性。
缺点:
1、它的运行需要较多次数的函数调用,如果调用层数比较深,每次都要创建新的变量,需要增加额外的堆栈处理,会对执行效率有一定影响,占用过多的内存资源。
2、递归算法解题的运行效率较低。在递归调用的过程中系统为每一层的返回点、局部变量等开辟了栈来储存。递归次数过多容易造成栈溢出等
注意:递归就是在过程或函数里调用自身;使用递归策略时要注意的几个条件
1、必须有一个明确的递归结束条件,称为递归出口。
2、递归需要有边界条件、递归前进段和递归返回段。
3、当边界条件不满足时,递归前进。当边界条件满足时,递归返回。
循环算法:
优点:速度快,结构简单。
缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环
029、创建数组的几种方式
三种方式:
1、var arr = new Array();
2、var arr = Array
3、var arr = [];
030、如果判断一个对象是不是另一个对象创建出来的
数组.instanceof Array
031、数组常用的一些方法
1、push: 在数组最后添加一个或者多个元素,返回添加后数组的长度
2、pop: 从数组最后取出一个元素,返回的是数组的最后一个元素(取出的元素)
3、unshift: 和push相反,从数组的第一位的前面开始添加
4、shift: 和pop相反从数组的第一位开始取,返回取出的值
5、sort 排序方法
6、reverse 反转
上面的6种方式都在原数组进行操作,会改变原本的数组
032、如何将数组转换为字符串?如何将字符串转换为数组
var str = 数组.join('')
var arr = 字符串.split('')
除此之外还有toString()
033、简单谈一谈关于值传递与引用传递
值传递:传递的是基本数据类型的数据(数据不会发生改变)
引用传递:传递的是对象(数组、对象)对象存储在堆空间中,自身可以发生改变
034、关于数组的排序请用至少2种方式进行排序
冒泡 选择 快速 代码自己写
035、什么是json?
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,用来来存储和表示数据
语法:
[
{键:值},
{键:值},
{键:值},
]
036、什么是ES5?js中的'use strict'是什么?目的是什么?
ECMA Script5:ECMA的第五次改版 时间:2009年
'use strict'js的严格模式
目的:
增加更多报错的场合,消除代码运⾏的⼀些不安全之处,保证代码 运行的安全。
提高编译器效率,增加运⾏速度。
为未来新版本的JavaScript做好铺垫
037、ES5中新增的数组的方法有哪些?
indexOf():返回第一次出现的下标
lastIndexOf():返回最后一次出现的下标
forEach():循环
map():映射
filter():过滤
reduce() 累加器
038、ES5中字符串新增的方法有哪些?
charAt() 获取指定位置上的字符
indexOf() 获取字符第一次出现的位置
substring() 截取字符串内容
slice() 截取
split() 将字符串分割成数组
replace() 替换
substr 返回一个从指定位置开始的指定长度的子字符串
039、如何将一个字符转换成ascii码?如何将一个数字转换成对应的字符
charCodeAt():将字符转换成ascii码
String.fromCharCode():将数字转换成对应的字符
040、请列举出Math常见的API
1、Math.random()=====随机数
2、Math.pow()====次方
3、Math.round()====四舍五入
4、Math.ceil() ===向上取整
5、Math.floor()===向下取整
6、Math.PI ====π
7、Math.max()===返回最大值
8、Math.min()===返回最小值
9、Math.sqrt() ===开方
041、在js中如何用方法将10进制的字符转换成16进制和8进制
数字.toString(16)
数字.toString(8)
042、如何创建时间对象
new Date()
043、如何创建未来或者过去的时间对象
var d = new Date('2017-10-20 22:22:22')
var d = new Date('2017/10/20 11:11:11')
044、如何获取时间戳
getTime();
045、常用的时间API
set/getFullYear()====获取年份
set/getMonth()=====获取或者设置月份 月份是从0开始的
set/getDate() ====获取或者设置日期
set/getHours()====获取或设置时
set/getMinutes()===获取或设置分
se/getSeconds() ===获取或设置秒
getDay();====如果是星期日的话返回是0;
046、如何将日期格式转化成为字符串
function dateString(date,sign){
if(sign==undefined){
sign='/'
}
return d.getFullYear()+sign+d.getMonth()+sign+d.getDate()+''+'周'+d.getDay()+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()
}
047、将指定格式字符串转化为日期两种方式
getTime()方法是把一个date对象转换为毫秒数
d.parse()方法是把一个日期格式的字符串转换为毫秒
048、js中异步的代码有哪些?
定时器 延时器
事件
ajax
049、url的组成部分有哪些
050、什么是浏览器缓存?
浏览器缓存(Browser Caching)是为了加速浏览,浏览器在用户磁盘上对请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览
051、如何打印当前浏览器的版本等信息
navigator.userAgent
返回包含浏览器版本等信息的字符串 ,常用于判断浏览器版本及使用设备(PC或者移动端
052 、在浏览器地址栏输入www.baidu.com后按下回车键会发生什么
1.域名解析
把域名解析ip地址 DNS域名解析系统
2.把ip发送到网络供应商 去找那个对应的主机服务器
3.TCP的三次握手 建立连接
4.开始发送请求 取回入口文件index.html
5.开始解析入口文件,并且取回需要的资源sources
6.进行
053、window.onload与window.onscroll的区别
window.onload:当页面加载完成的时候
window.onscroll:当页面滚动的时候
054、请简述下关于DOM的增、删、查
增---------createElement
var oDiv = document.createElement('div');
document.body.appendChild(oDiv);//只有追加后,页面上才会出现
2、删---------removeChild
语法:fatherObj.removeChild(childrenObj)
参数解释:
a、fatherObj:要删除子元素的元素对象
b、childrenObj:要被删除的子元素对象
3、查---------六种
document.getElementById('');常用
document.getElementsByClassName('');(ie9+)常用
document.getElementsByTagName('');常用
document.getElementsByName('');不常用
document.querySelector(选择器)(IE8+)(IE8+)
根据选择器返回匹配到的第一个元素
document.querySelectorAll(选择器);(IE8+)常用
根据选择器返回匹配到的所有的元素
055、请简述下关于Dom节点的分类
childNodes:获取所有节点 包括文本节点
节点分为3种类型:
1、元素节点 <span></span>
2、文本节点 <span>xxx</span>
3、属性节点 <span id ='xxx'></span>
可以通过nodeType这个属性查看节点的类型
nodeType == 1 元素
nodeType == 2 属性
nodeType == 3 文本节点
056、获取非行间样式
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
057、如何获取、设置、删除自定义属性
元素.getAttribute(属性名);
元素.setAttribute(属性名,属性值);
元素.removeAttribute(属性名);
058、innerHTML、innerText和outerHTML、outerText的区别(了解一下 背会就行不需要抄写)
- innerHTML 设置或获取位于对象起始和结束标签内的 HTML
- outerHTML 设置或获取对象及其内容的 HTML 形式
- innerText 设置或获取位于对象起始和结束标签内的文本
- outerText 设置(包括标签)或获取(不包括标签)对象的文本
innerText和outerText在获取时是相同效果,但在设置时,innerText仅设置标签内的文本,而outerText设置包括标签在内的文本。
不同之处:
简单的说innerHTML和outerHTML、innerText与outerText的不同之处在于:
1)、innerHTML与outerHTML在设置对象的内容时包含的HTML会被解析,而innerText与outerText则不会。
2)、在设置时,innerHTML与innerText仅设置标签内的文本,而outerHTML与outerText设置包括标签在内的文本。
3)、outhtml innerText(非W3C)
059、如何进行DOM节点筛选
1、可以通过nodeType
1 代表元素节点 2 代表属性节点 3 代表文本节点
function getNode(ele){
var aNode = ele.childNodes;
var newArr = [];
for(var i=0;i<aNode.length;i++){
if(aNode[i].nodeType == 1){
newArr.push(aNode[i])
}
}
return newArr;
}
060、 childNodes与children、attributes 的区别
如果想获取到子元素的element节点,最好使用children方法,childNodes方法以及firstChild方法在现代浏览器中使用,都会把元素标签中的空白节点检测出来,一般我们使用这两个方法都是为了获取到元素的元素节点,空白节点会给我们造成很多不必要的bug,而children方法则是只检测element元素节点
attributes:获取当前元素节点的所有属性节点集合
061、如何获取父级节点、上一个子级节点、下一个子级节点
nextElementSibling 后一个兄弟元素 (如果没有是null)
previousElementSibling 前一个兄弟元素 (如果没有就是null)
parentNode 获取当前节点的父节点
062、元素节点的创建、添加、删除、替换、克隆
1、创建:document.createElement('元素名');
2、添加:appendChild()====>插入到最后 insertBefore()====>插入到最前面
用法:
function append(obj,newEle){
var achildren = obj.children;
if(achildren.length>=1){
return obj.insertBefore(newEle,achildren[0])
} else{
return obj.appendChild(newEle)
}
}
3、删除:box.removeChild(node) 从元素中移除某个子元素
用法: 先找到父级节点然后在去删除子级节点
4、替换:box.replaceChild(子元素,父元素)
用法:
父元素.replaceChild(被替换成的元素,替换元素)
5、克隆:clone()
元素.clone();
如果里面传true的话会吧整个标签的所有节点都克隆,如果没有加true,只会克隆当前元素
063、浅谈关于文档碎片的理解
1、js操作dom时发生了什么?
每次对dom的操作都会触发"重排",这严重影响到能耗,一般通常采取的做法是尽可能的减少dom操作来减少"重排"
2、什么是文档碎片?
DocumentFragment是一个轻量级的文档对象,能够提取部分文档的树或创建一个新的文档片段,换句话说有文档缓存的作用
createDocumentFragment有什么作用?
多次使用节点方法(如:appendChild)绘制页面,每次都要刷新页面一次,效率也就大打折扣了,而使用document_createDocumentFragment()创建一个文档碎片,把所有的新节点附加在其上,然后把文档碎片的内容一次性添加到document中,这也就只需一次刷新就可以了
3、文档碎片有什么用?
将需要添加的大量元素 先添加到文档碎片 中,再将文档碎片添加到需要插入的位置,大大减少dom操作,提高性能
064什么是回流和重绘
当渲染树中的一部分或者全部因为元素的尺寸、布局、隐藏等改变而需要重新构建的时候,这时候就会发生回流。
每个页面都至少发生一次回流,也就是页面第一次加载的时候。
在回流的时候,浏览器会使渲染树中受到影响的元素部分失效,并重新绘制这个部分的渲染树,完成回流以后,浏览器会重新绘制受到影响的部分元素到屏幕中,这个过程就是重绘
什么时候会发生回流?
1、添加或者删除可见的DOM元素的时候
2、元素的位置发生改变
3、元素尺寸改变
4、内容改变
5、页面第一次渲染的时候
065、关于offsetX、offsetY、clientX、clientY、pageX、pageY、screenX、screenY的区别
offsetX、offsetY:
鼠标相对于事件源元素(srcElement)的X,Y坐标
clientX、clientY:
鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。
pageX、pagey:
类似于event.clientX、event.clientY,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这2个属性
screenX、screenY:
鼠标相对于用户显示器屏幕左上角的X,Y坐标。
066、如何在当前视窗的可见范围看见当前元素
scrollIntoView()
067、关于onkeydown和onkeypress的区别以及如何获取按下键盘的键盘码?
onkeydown:
1、所有的英文字符都是大写
2、功能键也会被识别
onkeypress
1、所有英文字符大小写都支持
2、所有功能键都不会被识别
3、组合键ctrl+回车的code值是10
e.keyCode || e.which