- try/catch 无法捕获 promise.reject
try/catch是同步;promise异步 - error 事件
当javascript运行出错,window会触发一个ErrorEvent接口的error事件,执行window.onerror()
window.onerror= function(message,source,lineno,colno,error){......}
window.addEventListener('error',function(event){......})
element.onerror = function(event){.......}
- 实现Function.prototype.bind
实现原理 - call bind apply
1)求一个数组中的最大、最小值
const arr = [1, 2, 34, 5, 6, 7, 0]
const max = Math.max.apply(null, arr)
console.log(max)
2)call和apply做继承
function Animal(name) {
this.name = name
this.showName = function() {
console.log(this.name)
}
}
function Cat(name) {
Animal.call(this, name)
}
var cat = new Cat('j')
cat.showName()
3)判断变量类型
let str='string'
let arr=[1,2,3,4]
let obj={name:'jack'}
Object.prototype.toString.call(str) //[object String]
Object.prototype.toString.call(arr) //[object Array]
Object.prototype.toString.call(obj)// [object Object]
fn.call(obj,arg1,arg2...)
fn.apply(obj,[arg1,arg2,arg3...]
const newFn =fn.bind(obj) newFn(arg1,arg2...)
-
mouseenter mouseover
-
正则表达式
var re = new RegExp('^[]{0-10}$')
-
浏览器内核
内核分为两部分:渲染引擎和JS引擎
渲染引擎:网页内容(html、xml、img等),添加css,计算网页显示方式
浏览器内核不同对网页的语法解释不同,渲染效果不同
JS引擎:解析和执行Javascript实现网页的动态效果 -
造成内存泄露的常见操作
内存泄露
任何对象在不需要依然存在
1)setTimeout的第一个参数是字符串,而非函数,引发内存泄露
2)闭包、控制台日志、循环 -
线程与进程的区别
1)一个程序至少一个进程,一个进程至少一个线程
2)多线程的意义在于一个应用程序中,有多个执行部分可以同时执行,但是操作系统并没有将多个线程看作多个独立的应用
3)每个独立的线程都有程序的入口、顺序执行、出口 -
eval函数作用
接受一个字符串string作为参数,并把这个参数作为脚本执行
eval('var str=1') // 声明str变量,并赋值
eval('2+3')
eval('function()')
- 实现 一个方法:add(2,5)和add(2)(5)结果都为7
let fun = function(x, y) {
if (arguments.length === 1) {
return function(i) { return x + i }
}
return x + y
}
console.log(fun(1, 2))
console.log(fun(1)(2))
- 1&&1、 1||0的结果
&&
:短路与,若前面为true,返回后面的值;若前面为false,返回前面的值
||
短路非,若前面为true,返回前面的值;若前面为false,返回后面的值
1&&2
:返回21||0
返回1 - 1和Number(1)的区别
Number()是函数类型
1是原始定义好的number类型 - prototype,原型和原型链
每个函数都有prototype原型对象
实例对象的__proto__指向构造函数的prototype对象 - script标签的defer和async
defer
:异步加载,不会影响后续dom渲染,顺序执行所有的script,在DOMcententLoaded事件调用之前执行
async
:异步加载,谁先加载完谁执行, - this
1)普通函数调用,this ->window
2) 对象的方法this->此对象
3)构造函数调用this->新对象
4)call、applythis->第一个参数
- 异步过程的构成要素?异步过程?
异步过程:1)主线程发起异步请求,相应的工作线程接收请求,异步函数返回
2)主线程继续执行后面的代码,工作线程执行异步请求
3)工作线程执行完毕,通知主线程
4)主线程接收,调用回调函数
异步函数Func(args,…callback)
Func(异步任务注册函数):发起异步过程
callback回调函数:处理结果
setTimeout(fn,1000)
-
消息队列和事件循环
1)主线程执行完当前任务,就会从消息队列中取出消息,并执行
2)工作线程对主线程通知之后,回调函数开始执行
3)如果一开始主线程没有提供回调函数,ajax线程接收到http响应后,不会通知主线程,也不会往消息队列中存放消息 -
session 和 cookie的区别
「1」sessioin存放在服务器,客户端不知道,
「2」cookie保存在客户端,服务器端知道
「3」session存储对象,cookie存储字符串
「4」session不区分路径,所有的session在任何地方都可访问;cookie设置路径参数 -
cookies,sessionStorage 和 localStorage 的区别
1)cookie数据始终在同源http请求中携带,在服务器和浏览器间传递
2)cookie有路径参数
3)sessionStorage和localStorage仅在本地保存,不会传递服务器
4)sessionStorage在当前页面关闭失效;localStorage始终有效,持久化数据;cookie可设置过期时间
5)sessionStorage在不同浏览器之间不同享;cookie和localstorage在所有同源窗口都是共享的 -
输入url到渲染的整个过程
详细过程
1)输入url地址,DNS域名解析,浏览器域名寻找ip地址
2)浏览器向服务器发送http请求
3)服务器接收请求,处理请求生成html代码,返给浏览器
4)浏览器接收服务器响应结果,页面解析渲染
5)解析html,构建dom树,css样式
6)布局
7)绘制 -
公钥加密和私钥加密
公钥:用于对数据进行加密
私钥:用于对数据进行解密
如何确保表单提交的密码字段不被泄露?
「1」form表单提交,对密码字段并不加密而是以明码形式传输数据
「2」若对数据进行加密,使用https安全传输协议 -
验证码
概念:将一串随机产生的数字或符号,生成一副图片,图片加入干扰像素(防止OCR)由用户肉眼识别其中的验证信息,输入表单提交网站验证 -
截取字符串abcdefg中的efg
console.log('abcdefghi'.slice(4)) // efghi
console.log('asdsdfff'.substring(4)) // dfff
- 判断一个字符串中出现次数最多的字符,并统计次数
在这里插入代码片
-
document.write 和innerHTML的区别
1)document.write直接写入到页面的文档流
2)innerHTML是DOM页面元素的一个属性,代表该元素的html内容
3)innerHTML将内容写入某个dom节点,不会整个页面重绘
4)document.write重写整个document,写入字符串的html;innerHTML是htmlElement的属性,是一个元素内部的html内容 -
js识别不同浏览器信息
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
if (userAgent.indexOf("Firefox") > -1) {
return "Firefox";
} //判断是否Firefox浏览器
if (userAgent.indexOf("Chrome") > -1) {
return "Chrome";
} //判断是否Google浏览器
......
- js常见的内置对象
Object 、Math 、String 、Array 、Number 、Function 、Boolean 、json
- 写一个方法:求一个字符串的字节长度
/* 假设:一个英文字符占用一个字节,一个中文字符占用两个字节 */
var str = 'dsfsdlkjfsdn喜欢你sd'
function getBytes(str) {
var len = str.length
var bytes = len
for (var i = 0; i < len; i++) {
if (str.charCodeAt(i) > 255) { bytes++ }
}
return bytes
}
console.log(getBytes(str))
-
new操作符
具体干了什么?
创建空对象:this引入该对象
属性和方法被加入this引用的对象中、
新创建的对象由this引用
1)创建一个空对象let obj =new Object()
2)继承构造函数的原型obj.__proto__=== Func.prototype
3)绑定this值,this指向该对象obj,并指向Func函数体
4)判断Func的返回值类型:值类型-obj;引用类型-引用类型的对象 -
json
格式:键值对{'name‘:‘jack’,‘age’:12}
基于javascript的一个子集;json是轻量级数据交换格式 -
性能优化
1)内容优化:减少http请求;减少DNS查找;使用Ajax缓存;减少dom,iframe数量,避免404和重定向
2)服务器优化:使用内容分发网络CDN;GZIP压缩;设置ETag;使用GET方法;提前刷新缓存区
3)Cookie优化:减少cookie大小;针对 Web 组件使用域名无关的 Cookie
4)css优化:放置html顶部;避免使用css表达式;使用link
;
5)javascript优化:放置html底部;外部引入js和css文件;最小化dom访问
6)img优化:css sprite
优化图片;不要在html中使用缩放图片 -
js格式化数字(每三位加逗号)
-
合并数组
Array.concat()
Array.push.apply(arr1, arr2)
-
节点列表Node.list转换为数组
document.querySelectorAll(“p”) 方法,返回一个 DOM 元素的数组 — 节点列表对象;方法:[ ].slice.call(elements)
var elements = document.querySelectorAll("p"); // NodeList
var arrayElements = [].slice.call(elements); // 现在 NodeList 是一个数组
var arrayElements = Array.from(elements); // 这是另一种转换 NodeList 到 Array 的方法
- js中的ready和onload事件的区别
ready
当dom结构加载完毕执行,相当于$(function(){js....})
onload
html页面元素全部加载完毕再执行,包括dom结构,img,css - js的两种回收机制
1)标记清除:当变量进入某环境时标记一下,离开时清除此标记
1、垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记
2、然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记
3、而在此之后再被加上的标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。
4、最后,垃圾收集器完成内存清除工作。销毁那些带标记的值并回收它们所占用的内存空间。
2)引用计数:跟踪记录每个值被引用的次数 - 闭包的理解
1.可以读取函数内部的变量
function f1() {
var n = 999; //函数内部变量声明使用var,否则为全局变量
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 999
2.变量始终保存在内存中
function f1() {
var n = 999;
nAdd = function () { n += 1 } // nAdd 相当于全局变量
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 999
nAdd();
result(); // 1000 f1中的局部变量n一直保存在内存中,并没有在f1调用后直接删除
- js中判断一个变量是数组还是对象?
typeof
[ ]和{ } 都返回Object
1)typeof+length(Array.length)
2)instanceof (先 Array-后Object)
3)constructor(2).constructor === Number // true
4)Object.prototype.toString.call() - ES5和ES6继承的区别
ES5继承通过prototype或构造函数继承
ES6通过class定义类,类有构造方法,类之间通过extends实现继承;子类必须在constructor方法中调用super方法,继承父类的this对象 - 翻转一个字符串
先将字符串转成一个数组,然后用数组的 reverse() + join() 方法。
let z = 'hrmml dsd'
// 将字符串转成数组 // let arr = z.split('')
let arr = [...z].reverse().join('')
- 堆和栈的区别
「1」空间分配区别 - 栈:操作系统自动分配释放,存放函数的参数值,局部变量
- 堆:程序员分配释放
「2」缓存方式区别 - 栈使用一级缓存,被调用时处于存储空间,调用完毕立即释放
- 堆是二级缓存,生命周期由虚拟机的垃圾回收算法决定
「3」数据结构 - 堆可以被看成一棵树,如:堆排序
- 栈:先进后出,新添加的数据位于栈顶