什么是原型链?怎么实现继承?call、apply、bind的区别?什么是作用域链?什么是闭包?词法作用域?ajax和jsonp?jsonp为什么只支持get?基本数据类型?堆栈区别?null和undefinedjs怎么实现异步?eventloop?js引擎线程执行过程?发布/订阅者和观察者区别?base64网络传输? 网络传输只能传输可打印字符持续动画? setTimeout、setInterval、window.requestAnimationFrame js多范式语言?防抖,节流?事件委托?循环 for...in Object.keys for...of Object.getPropertyNames模块化、组件化?this?类数组?转数组?判断数组,数组去重?instanceof与isArray Object.prototype.toString().call([]) ?instanceof与isArray判断对象是否为数组?localStorage、cookie、sessionStorage深拷贝、浅拷贝?垃圾回收机制?js组件化、模块化?formData和原生的ajax有什么区别?Content-type内存泄漏?in 和hasOwnProperty的区别?https://www.cnblogs.com/ziwuge/archive/2011/09/27/2193385.html复制代码
深拷贝
黑科技 JSON.parse(JSON.stringify(obj)) 递归拷贝 Object.create(oldObj)复制代码
原型链
每一个对象都会在内部初始化一个属性,就是(prototype)原型。 当访问一个对象是否存在属性或方法时,优先在对象自身寻找该属性,如果有 就使用自身的属性或方法;没有就在创建这个对象的构造函数的原型上向上查 找,以此类推找到object.prototype对象,还没找到就返回undefined;复制代码
null 和 undefined
null是一个空对象,没有任何属性和方法 undefined是未定义,此处应该有个值,未赋值复制代码
js是多范式语言
命令式 基本的逻辑控制、迭代语句等。 函数式 scope Chain (作用域链) 面向对象 Prototype Chain(原型链)复制代码
闭包
- 可以读取自身函数外部的变量(沿着作用域链寻找)
- 让这些外部变量始终保存在内存中
定时器
实际上要等到当前脚本的所有同步任务执行完复制代码
EventLoop 执行栈执行顺序。
宏任务:script整体 setTimeout setImmediate I/O UI 微任务:process.nexTick promise.then async script(主程序代码)—>process.nextTick—>Promises...——> async ——> setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering复制代码
类数组
见类数组对象有arguments对象、通过Node.childNodes得到的NodeList对象、通过document.getElementsBy...得到的HTMLCollection对象、element.attributes得到的NamedNodeMap对象等。 Array.prototype.sort.call(arrLikeObj); 劫持应用数组方法 Array.prototype.slice.call(arrLikeObj);//转化为数组 Array.from(arrLikeObj);//es6转化为数组 Object.prototype.toString().call() 判断是否是数组复制代码
localStorage
localStorage.setItem('myCat', 'Tom'); localStorage.getItem('myCat'); localStorage.removeItem('myCat'); localStorage.clear();// 移除所有 复制代码
formData和原生的ajax有什么区别
form的Content-type默认值:Content-type:application/x-www-form-urlencoded ajax默认值Content-Type是text/plain;charset=UTF-8。复制代码
jsonp为什么只支持get
JSONP的最基本的原理是:动态添加一个是一致的,因为他的原理实际上就是 使用js的script标签 进行传参,那么必然是get方式的了,和浏览器中敲入一个url一样复制代码
垃圾回收原理浅析
标记清除 标记变量进入环境,离开环境。引用计数 释放引用次数为0的值所占的内存。复制代码
数组去重
// 最简单去重function uniq(array){var temp = []; //一个新的临时数组for(var i = 0; i < array.length; i++){ if(temp.indexOf(array[i]) == -1){ temp.push(array[i]); }}return temp;}var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];console.log(uniq(aa));// 排序相邻去重/** 给传入数组排序,排序后相同值相邻,* 然后遍历时,新数组只加入不与前一值重复的值。* 会打乱原来数组的顺序* */function uniq(array){ array.sort(); var temp=[array[0]]; for(var i = 1; i < array.length; i++){ if( array[i] !== temp[temp.length-1]){ temp.push(array[i]); } } return temp;}var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];console.log(uniq(aa));// set去重function dedupe(array){ return Array.from(new Set(array));}dedupe([1,1,2,3]) //[1,2,3]复制代码
ajax
过程:(1)创建一个异步调用对象XMLHttpRequest对象.var xhr=new XMLHttpRequest();0(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息;1(3)设置响应HTTP请求状态变化的函数.xhr.open('post','1.txt',true);2(4)发送HTTP请求. xhr.send();3(5)获取异步调用返回的数据。4复制代码
xhr.onreadystatechange=function(){ if (xhr.readyState==4) { if (xhr.status==200) { alert(xhr.responseText); }else{ alert("出错了:"+xhr.status); } }; } readyState 属性表示Ajax请求的当前状态。它的值用数字代表。 0 代表未初始化。 还没有调用 open 方法 1 代表正在加载。 成功调用open方法之后 2 代表已加载完毕。调用send方法并接收HTTP响应头之后 3 代表交互中。 HTTP响应内容开始加载 4 代表完成。 HTTP响应内容完成加载复制代码
this
//this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window;var name = "The Window";var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; }};alert(object.getNameFunc()());复制代码
类型转换
对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:
- 如果已经是原始类型了,那就不需要转换了
- 调用 x.valueOf(),如果转换为基础类型,就返回转换的值
- 调用 x.toString(),如果转换为基础类型,就返回转换的值
- 如果都没有返回原始类型,就会报错
模块化
优点
- 解决命名冲突
- 提供复用性
- 提高代码可维护性
手段:
- 立即执行函数
- AMD CMD
- CommonJS
- ES Moudle
new 实现
function create() { let obj = {} let Con = [].shift.call(arguments) obj.__proto__ = Con.prototype let result = Con.apply(obj, arguments) return result instanceof Object ? result : obj}复制代码