var,let,const的异同?
1.都是用来定义变量的关键字 2.var具备声明提升 3.let,const必须先定义后使用,不具备声明提升,不能重复定义变量,块级作用域,暂时性死区 块级作用域(变量在该作用域中不会丢失) 暂时性死区(当内部变量与外部变量同名时,内部变量屏蔽外部变量) 4.const修饰的变量为只读变量,且必须初始化
for...in...和for...of...
1.for...in... 遍历的是下标,通常用来遍历json对象 2.for...of... 针对于没有下标的容器,进行遍历
箭头函数
箭头函数:匿名函数的一种写法 特点: 1.如果只有一个参数,可以省略圆括号 2.如果函数体只有一条语句,则可以省略花括号 3.如果函数体只有一条语句,则自带return
普通函数与箭头函数的区别
1.外形不同:箭头函数使用箭头定义,普通函数没有 2.箭头函数全都是匿名函数,普通函数可以有匿名函数,也可以有有名函数 3.箭头函数不能用于构造函数,普通函数可以用于构造函数,创建实例化对象 4.箭头函数中的this指向不同,this出现在箭头函数中时,代表其父元素的前缀;this与普通函数连用(除了事件体和构造函数),代表调用该函数的对象。 5.箭头函数不具有arguments对象,每一个普通函数调用后都具有一个arguments对象(arguments:是函数的内置对象,保存着所有实参的伪数组)。 6.箭头函数不具有prototype原型对象,不具有super,不具有new.target。(原型对象:prototype是函数对象的一个属性,主要针对于构造方法;作用:存储所有实例对象共享的属性和方法。)
普通函数和构造函数的区别
1.构造方法必须和new连用 2.构造方法习惯上函数名首字母大写 3.构造函数体内不能有返回值(因为默认返回的是new出来空间的地址)
内置基本类型:
数字类型:number 字符串:string boolean: undefined: null: 引用类型: object、正则、数组、函数、Date等
内置基本类型和引用类型在内存中存储的区别
1.内置基本类型在内存中只有一块栈空间,存储的是就是数值 2.引用类型在内存中有两块空间,一块是栈空间,存储的是堆空间的地址。一块是new出来的堆空间,存储的是真正的数值。
json对象
json对象:描述数据的一种格式,将若干繁杂的属性封装为一个整体,可以直接通过json对象,操作各个属性。 1.定义,由{}括起来的键值对,每两个键值对用逗号分开(key:value) 注意事项:所有的key用双引号括起来 2.属性的访问 a.通过点运算符访问(常用) 对象名.属性名 b.下标法 对象名[属性名] 3.为json对象添加新的自定义属性(增加属性) 对象名.新属性名 = 属性值 对象名[新属性名]=属性值 4.删除属性 delete 对象名.属性名 delete 对象名[属性名] 5.遍历json for...in 6.json和字符串的相互转换 字符串->json对象------JSON.parse json对象->字符串------JSON.stringify
=, == ,===的异同?(面试题)
1. = 赋值运算符,将右值赋值给左值,所有和=连接的复合赋值运算符优先级都是最低的 2. == 逻辑等,判断左值和右值是否相等,可以支持数据类型转换 3. === 严格逻辑等,不支持数据转换,必须数值和类型都一致才为true
字符串和数字之间的转换
1.隐式转换 1)当字符串和数字进行运算时,凡是通过加号连接的,结果全部都转为字符串,效果等价于字符串拼接 2)除了加号以外的运算符,-,*,/,%等,计算的结果全部为数字 注意: a.两个数值字符串做除了+以外运算,结果也为数字 console.log("10" * "10"); //100 b.如果遇到了非数字字符串,做+以外的运算,结果为NaN, NaN也是数字类型 console.log("abc" - 10); //NaN 2.显示转换 1)字符串转数字 parseInt(字符串或有小数点的数字):将内容转换成没有小数点的数字 parseFloat(字符串):将内容转换成有小数点的数字 Number(有小数点的字符串||没有小数点的字符串):转换为数字 2)数字转字符串 数字对象.toString():返回该数字的字符串形式
四、三目运算:条件运算符 表达式1?表达式2:表达式3 表达式1是一个布尔值,根据表达式1的结果,返回表达式2或表达式3 表达式1为true,返回表达式2 表达式1为false,返回表达式3 c = a > b ? a : b; console.log(c);
五、变量的声明提升 当遇到没有定义的变量时,会自动进行声明提升 系统会偷偷在首行定义该变量且赋值为undefined
六、严格模式 必须使用定义过的变量 被"use strict"修饰的作用域,所有变量必须定义才能使用
七、BOM和DOM 1、BOM browser object model //浏览器对象模型 2、DOM 节点 document object model //文档对象模型
八.阻止冒泡:在事件传播的子元素上,通过事件对象调用函数 兼容写法: e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
九.阻止浏览器的默认行为 兼容写法: 1). e.preventDefault ? e.preventDefault() : e.returnValue = false; 2).return false;
兼容问题
1.事件对象的兼容: document.onclick = function(evt){
var e = evt || event;
console.log(e); }
2.获取键盘asc码的兼容写法: var key = e.keyCode || e.which || e.charCode;
3.阻止冒泡事件的兼容写法: e.stopPropagation?e.stopPropagation():e.cancelBubble = true;
4.阻止浏览器的默认行为: e.preventDefault?e.preventDefault():e.returnValue = false;
5.事件委托的兼容方法: var target = e.srcElement || e.target;
6.兼容性的获取浏览器滚动条高度 document.body.scrollTop || document.documentElement.scrollTop;
学习API(函数)的思想 1.功能 2.参数 3.返回值 4.看案例
数组的API
push 功能: 尾插,向数组末尾添加若干元素
参数: push(参数1, [参数2, 参数3...]) 返回值: 新数组的长度
pop 功能:尾删
参数:无 返回值:被删除的元素
unshift 功能:头插
参数:unshift(参数1, [参数2, 参数3...]) 返回值:新数组的长度
shift 功能:头删
参数:无 返回值:被删除的元素
splice 功能:数组删除且替换
参数:splice(起始位置,偏移量,[参数1,参数2...]) 返回值:被删除的元素
slice 功能:截取数组区间
参数:slice(起始位置,结束位置):左闭右开 [初始位置,结束为止) 返回值:被截取的区间 var arr = [1, 2, 3, 4, 5]; var arr1 = arr.slice(1, 3); console.log(arr1);
reverse 功能:反转数组中元素的顺序,且会改变原数组
参数:无参 返回值:反转后的数组
concat 功能:数组的拼接,不会改变原数组
参数:concat(新数组) 返回值:新拼接的数组
join 功能:将数组转为字符串
参数:join([分隔符号]),默认逗号分割 返回值:转换的字符串
indexOf 功能:查找目标元素
参数:indexOf(目标元素) 返回值:找到返回下标,找不到返回-1 可去重 var arr = [5, 6, 4, 7, 8, 3, 9]; var x = arr.indexOf(18); console.log(x);
字符串的API
asc码:每个字符都对应一个数字,这个数字就是asc码
字符和对应的asc码是无条件等价的
65 'A';97 'a';48 '0';32 空格;13 回车
charAt(索引):返回索引对应的字符
console.log(str.charAt(0));
charCodeAt(索引):返回索引对应的字符的asc码值
console.log(str.charCodeAt(0));
fromCharCode 功能:返回asc码对应的字符
参数:fromCharCode(asc1,asc2...) 返回值:asc码对应的字符 注意事项:该方法直接通过类名String调用
indexOf 功能:查找目标元素
参数:indexOf(目标元素) 返回值:找到返回下标,找不到返回-1 可去重
lastIndexOf("abc") 查找字符串最后一次出现的位置 如果没找到 返回-1
var str = "hello world"; console.log(str.lastIndexOf("o"));
replace 功能:替换,用参数2替换参数1
参数:replace(被替换字符串,替换的字符串) 返回值:被替换的字符串; 只能替换一次
slice / substring 截取字符串
参数:[起始位置,结束为止) 左闭右开
split 功能:将字符串按分隔符转为数组
参数:split(分隔符) 返回值:一个字符串数组
字符串转大写 toUpperCase();
字符串转小写 toLowerCase();
str.includes(参数): 返回布尔值,表示是否找到了参数字符串。
str.startsWith(参数):返回布尔值,参数是否在源字符串的头部。
str.endsWith(参数): 返回布尔值,参数是否在源字符串的尾部。
Math
1.Math.floor(参数);向下取整 1.1---1,(-1.2)---(-2) 2.Math.ceil(参数);向上取整 1.1---2,(-1.2)---(-1) 3.Math.round(参数);四舍五入取整 1.2---1,1.9---2,(-1.9)---(-2) 4.Math.sqrt(number) 开平方根 5.Math.pow(m,n) 返回m的n次方 6.Math.min(1,-2,3,4) 返回N个数最小值 7.Math.max(1,-2,3,4)返回N个数最大值 8.Math.abs(number) 返回绝对值 9.Math.random():返回0~1之间的数,左闭右开
循环定时器
setInterval(回调函数,时间间隔):返回值为关闭定时器的钥匙 clearInterval(关闭定时器的钥匙)
延时定时器
setTimeout(回调函数,时间间隔):返回值为关闭定时器的钥匙 clearTimeout(关闭定时器的钥匙)
document 找html元素,转换成js对象
找单个元素(返回一个元素)
document.getElementById("ID名"):返回ID对应的元素 (ID名不加#) document.querySelector("选择器"):返回ID,类,标签对应的单个元素 (ID名加#,类加.)
找批量元素(返回数组)
document.getElementsByTagName("标签名"):批量返回标签名对应的HTML元素,存放在数组中 document.getElementsByClassName("类名"):批量返回类名对应的HTML元素,存放在数组中 (类不加.) document.getElementsByName("name名"):批量返回name名对应的HTML元素,存放在数组中 document.querySelectorAll("选择器");批量返回类或标签对应的元素,存在数组中
Dom节点的操作
增
a.创建 createElement document.createElement("标签名"):返回创建好的dom对象
b.追加 1). 父节点.appendChild(子节点) 在最后面添加 2). insertBefore(目标节点, 参照节点);将目标节点添加至参照节点之前
删
dom.remove()
Dom节点遍历的属性
父找子
firstElementChild 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 lastElementChild 返回节点的最后一个子节点 childNodes:返回父元素的所有子节点(数组),包含dom节点和文本节点 children:返回父元素的所有子节点(数组),只包含dom节点
兄弟节点的遍历
nextElementSibling 下一个节点 previousElementSibling 上一个节点
子找父
parentNode
常见的浏览器以及内核还有前缀
1.谷歌chrome======内核(webkit)========前缀(-webkit-)
2.苹果safari======内核(webkit)======前缀(-webkit-)
3.火狐firefox=====内核(gecko)=======前缀(-moz-)
4.欧朋opera=======内核(presto)======前缀(-o-)
5.IE=============内核(trident)=====前缀(-ms-)
数组去重
1、set let arr = [1,"heihei",1,2,2,3,4,4,5,5,1,"heihei"];
let set = new Set(arr);
//通过Array.from(集合):将集合转化为数组
arr = Array.from(set);
console.log(arr);
2、indexOf var arr=[5,6,7,4,8,5,6,7,8,1,2,1]; var newArr= []; for(var i=0;i<arr.length;i++){ if (newArr. index0f(arr[i]) == -1) { //在newArr中没有找到arr[i]这个元素 newarr. push(arr[i]); //那刚好把没找到元素尾插至arr1中 } console. log(newArr);
3、includes
var arr = [2, 4, 3, 2, 5, 6, 6, 9]; var newArr = []; for (var i = 0; i < arr.length; i++) { if (!newArr.includes(arr[i])) { newArr.push(arr[i]); } } console.log(newArr);
ES6方法创建类
class 类名{ //构造方法 constructor() { //普通方法 } }
深浅拷贝
浅拷贝 // let arr = new Array(1,2,3); // let arr1 = arr; // arr[0] = "强烈抗议"; // console.log(arr); // console.log(arr1);
深拷贝 // let arr = new Array(1,2,3); // let arr1 = [];
// for(let i=0; i<arr.length; i++){ // arr1.push(arr[i]); // } // arr[0] = 82; // console.log(arr); // console.log(arr1);
重绘和回流
什么是重绘?
重绘: 当渲染树中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,而不会影响布局的操作,比如 background-color,我们将这样的操作称为重绘。
什么是回流?
回流:当渲染树中的一部分(或全部)因为元素的尺寸、布局、隐藏等改变而需要重新构建的操作,会影响到布局的操作,这样的操作我们称为回流。
常见引起回流属性和方法:
任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发回流。
(1)添加或者删除可见的 DOM 元素; (2)元素尺寸改变——边距、填充、边框、宽度和高度 (3)内容变化,比如用户在 input 框中输入文字 (4)浏览器窗口尺寸改变——resize事件发生时 (5)计算 offsetWidth 和 offsetHeight 属性 (6)设置 style 属性的值 (7)当你修改网页的默认字体时。
回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。
面向对象
面向对象就是将问题抽象成若干object对象,然后对这些对象进行编程,将对象的属性和方法封装到类中,让他们具有一定的功能。
好处: 1).随着问题规模的增加,添加新的类型就可以了 2).复用性大大提高
面向对象的三大特性: 1). 封装:将若干函数和属性封装成一个整体 2). 继承:将已有的类的属性和方法拿过来使用 3). 多态:不同对象调用相同的函数执行不同的功能效果
ajax
ajax的概念及作用
概念: ajax,异步交互的javascript和XML,是一种可以实现页面在发请求时,无需更新整个页面,只需对局部内容更新的技术。 作用: 1. 更自然、流畅的用户体验,对用户的操作即时响应 2. 在不中断用户操作的情况下与Web服务器进行通信 3. 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果 4. 通过局部更新页面降低网络流量,提高网络的使用效率
ajax操作步骤
1.创建xhr对象 2.调用open方法(设置请求) xhr.open("请求方式","服务器地址",是否异步true/false); 3.调用send(发送请求) 4.等待 5.接收响应
状态码
onreadystatechange readystate状态码发生改变时触发该事件,只有234状态会触发该事件 readystate 状态码的含义 0.代表xhr对象创建 1.调用了open方法 2.调用了send方法,发送了出去 3.数据发送到了服务器 4.服务器接收数据且处理完毕,准备响应 status: http协议正常通讯的状态码 200 OK //客户端请求成功 404 Not Found //请求资源不存在,输入了错误的URL 5xx //服务器出现错误 2开头:(请求成功)表示成功处理了请求的状态代码 200:(成功)服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。 3开头:请求被重定向 4开头:(请求错误)这些状态码表示请求可能出错,妨碍了服务器的处理 400:(错误请求)服务器不理解请求的语法,参数错误 401:(未授权)请求要求身份验证。对于需要登录的网页,服务器可能返回此响应 403:(禁止)服务器拒绝请求 404:(未找到)服务器找不到请求的网页 408:(请求超时)服务器等候请求时发生超时 5开头:(服务器错误) 500:(服务器内部错误)服务器遇到错误,无法完成请求 502:(错误网关) 503:(服务器不可用) 504:(网关超时) 505:(HTTP 版本不受支持)
ajax中get传参和post传参区别
get传参:请求参数添加在url后 post传参:1.请求参数添加在send的参数中 2.open和send之间需要设置请求头
http协议发请求get和post的区别?
get:效率高,安全性低,携带数据量小 post:效率低,安全性高,携带数据量大
接口
接口:后端给前端提供的服务器文件,前端根据不同的接口发出不同的请求,获取对应的响应。 接口的四要素: type:get/post url:服务器地址 data:请求参数 resText:响应数据
Promise
1.概念: Promise是一个对象,该对象是处理异步操作的一种方法。 Promise对象类似于一个容器,可以存放异步操作。(几乎只针对发请求和接响应) Promise有三种状态:1)进行中 2)已成功 success 3)已失败 failed 2.作用 可以将回调嵌套的写法,改为平级调用。(通过then属性) 3.Promise.all 和 Promise.race 两种方法 Promise.all场景:一个页面渲染需要同时发送多个请求,等待所有的请求结束时,统一接收响应。 Promise.race场景:获取同样的数据,有n个服务器,可以一次发多个请求,谁快就获取谁的响应。
异步与同步
同步:代码按照顺序执行,必须先执行完前一步,才能执行后一步 异步:代码在遇到消耗等待时间的代码时,会先跳过异步代码,先执行后续代码,直至异步代码消耗完等待时间后,再执行异步代码。 三种异步代码: 1.定时器 2.事件体 xxx.onclick = function(){事件头 事件体 } 3.发请求接响应 4.动画 结论: 当同步代码和异步代码同时出现时,先执行同步,后执行异步。 只有同步遵循自上而下的执行顺序,异步谁先消耗完等待时间,谁先执行。
跨域
跨域:网站A的页面访问网站B服务器的某个文件,跨域名访问。 同源策略:浏览器的安全机制,浏览器只能访问同IP、同端口、同协议的文件。
实现跨域访问:
前端跨域(jsonp) jsonp:是一种跨域的技巧
jsonp的实现步骤: 1.src属性是可以跨域的 2.script标签和src结合可以实现跨域导入文件 3.前端与后端约定一个函数名,前端写函数定义,后端写函数调用 4.后端通过模拟函数调用,将参数传递给前端
后端跨域(CROS) header("Access-Control-Allow-Origin:*");
请问jsonp是不是ajax中实现跨域访问的技术
jsonp不是AJAX中实现跨域访问的技术 1、jsonp没有使用XMLHttpRequest对象 2、jsonp只是一种跨域的技巧 3、jsonp只支持get方式 4、ajax支持get方式和post方式
http协议
超文本传输协议,是一个基于请求和响应的协议。
闭包
闭包的概念:函数嵌套函数,被嵌套的函数称为闭包函数。
闭包的作用:可以在函数外部使用函数的局部变量。
闭包实现的步骤: 主函数定义局部变量,嵌套定义子函数。 子函数中使用主函数的局部变量,主函数将子函数作为返回值, 在外部通过一个全局变量,绑定主函数的返回值, 从而将子函数和子函数中使用的局部变量变为全局生命周期, 这样就可以在主函数外界使用局部变量了。
闭包的缺陷: 大量使用闭包,打破了垃圾回收机制,延长了局部变量的生命周期,可能会造成内存泄露。
JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时,这块内存还存在着,没有被释放,导致该内存无法被使用, 垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
this指向
-
this:函数的内置对象,作用域在函数体内
1.this与事件体连用,代表触发该事件的元素本身 2.this与普通函数连用(除了事件体和构造函数),代表调用该函数的对象 3.this出现在构造方法中,代表new出的对象 4.this出现在箭头函数中时,代表其父元素的前缀
apply,call,bind的异同?
相同点:它们都是用来改变函数对象的this指向 不同点:1.bind通常针对于匿名函数,apply和call针对有名函数 2.apply,call第二个参数不同,apply为数组,call单独写出 3.bind方法调用时,并不是直接调用原函数,等价创造了一个新的函数对象,还需要重新调用
[继承]
继承
继承:父类可以派生出子类,子类具备父类的属性和方法;子类还可以添加自己新的属性和方法。 继承的作用:提高代码的复用性。
原型对象
原型对象:prototype是函数对象的一个属性,主要针对于构造方法(类)。 作用:存储所有实例化对象共享的属性和方法
一、原型继承 概念:用子类的原型对象指向父类的实例化对象; 作用:子类实例化对象可以直接使用父类创造的属性和方法,并且子类可以添加新的属性和方法。 缺陷:1.无法在子类对象构造时,初始化父类派生给子类的属性 2.必须先实现继承关系,再为子类添加新的方法,否则会覆盖
子类的实例化对象,是如何访问父类的属性和父类的方法,及子类的属性和子类的方法。
原型图: 子类对象可以直接访问自身new出的属性,通过_proto_可以访问该类原型对象上的属性和方法, 该类原型对象指向其父类的实例化对象,所以可以访问父类的属性 父类实例化对象的_proto_也指向自身类的prototype,所以可以访问父类原型对象的属性和方法
原型链:
多个类纵向继承,在访问任意属性时,先在自身查找该属性,找不到去原型找, 再找不到就去找父级元素,依次向上找。(向上查找,祖宗类都找不到,就报错)
二、apply和call"继承" 作用:可以使子类对象在构造时,初始化父类派生给子类的属性 缺陷:子类对象无法访问原型对象上的属性和方法
三、混合继承 1.原型继承prototype上的属性和方法 2.apply和call继承自身new出的属性
四、Es6的继承 语法: class Student extends Human{ constructor(id, name, score){ super(id, name); this.score = score; } } super代表的是父类的构造方法 super必须写在第一行
[深拷贝和浅拷贝]
深拷贝和浅拷贝
拷贝:用已有对象初始化一个新对象 深浅拷贝只针对于引用类型 内置基本类型和引用类型在内存中存储的区别: 内置基本类型:只有一块栈空间,存储的是数据本身 引用类型:有两块空间,一块栈空间,一块堆空间;栈存储的是堆空间的地址,堆存储的是真正的数据。 1.浅拷贝:只拷贝地址,但并不开辟空间,两个对象共享同一个空间,其中一个改变了数值,另一个也会被修改。 // let arr = new Array(1,2,3); // let arr1 = arr; // arr[0] = "强烈抗议"; // console.log(arr); // console.log(arr1);
2.深拷贝:开辟空间且赋值,两个对象都有独立的空间,被拷贝的对象,只是和原对象数值相同。 // let arr = new Array(1,2,3); // let arr1 = []; // for(let i=0; i<arr.length; +i++){ // arr1.push(arr[i]); // } // arr[0] = 82; // console.log(arr); // console.log(arr1);
typeof 和 instanceof 的异同?
相同:判断某个对象是否属于某个类型。 不同: 1.typeof用来判断内置基本类型,如number,string,boolean; 2.instanceof用来判断引用类型,返回布尔值。
cookie
作用1:会话生命周期 在页面间共享传递数据,可以理解为cookie是一个变量。 会话指一个网页从打开到页面完全关闭的过程。 官方概念,cookie称为会话跟踪技术,只要会话存在,cookie可以在会话间的页面共享传递数据。 作用2:长生命周期 cookie可以长期保存在用户电脑的磁盘中,例如实现七天免登陆效果。
cookie和localStorage及sessionStorage的异同?
localStorage 等价于长生命周期的cookie sessionStorage 等价于会话级别的cookie 1.数据的生命周期: cookie:一般由服务器生成,可设置失效时间。如果在浏览器端生成cookie,默认是关闭浏览器后失效。 localStorage:除非被清除,否则永久保存。 sessionStorage:仅在当前会话下有效,关闭页面或者浏览器后被清除。 2.存放数据大小 cookie:4KB左右 localStorage和sessionStorage:一般4~5MB; 3.与服务器端通信 cookie:每次都会携带在http头中,如果使用cookie保存过多数据会带来性能问题; localStorage和sessionStorage:仅在浏览器中保存,不参与和服务器的通信。 4.易用性 cookie:需要自己封装,源生的cookie接口不友好 localStorage和sessionStorage:源生接口比较好用。
懒加载
延迟加载, 当页面需要加载大量图片时,优先加载可视窗口的图片 使用场景瀑布流: 懒加载原理 <img src="url地址"> 每个img都有src属性,当src属性发送请求时,就会下载数据, 如果src属性开始没有url地址,该img标签便不会发送请求, 开始不要让所有的img标签都存储url, 将url保存在一个自定义属性中, 等img标签进入加载条件时,再将url赋值给src 加载条件 if (图片.top < 可视窗口的高度 + 滚动条的高度){ oImg[i].src = oImg[i].data_url; }