js 整理

239 阅读5分钟
什么是原型链?怎么实现继承?
call、apply、bind的区别?
什么是作用域链?什么是闭包?词法作用域?
ajax和jsonp?jsonp为什么只支持get?
基本数据类型?堆栈区别?null和undefined
js怎么实现异步?
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(原型链)

闭包

  1. 可以读取自身函数外部的变量(沿着作用域链寻找)
  2. 让这些外部变量始终保存在内存中

定时器

    实际上要等到当前脚本的所有同步任务执行完

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的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了。
可以说jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的,因为他的原理实际上就是 使用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 = {
&emsp;&emsp;name : "My Object",
&emsp;&emsp;getNameFunc : function(){
&emsp;&emsp;&emsp;&emsp;return function(){
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;return this.name;
&emsp;&emsp;&emsp;&emsp;&emsp;};
&emsp;&emsp;&emsp;}
};
alert(object.getNameFunc()());

类型转换

对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:

  1. 如果已经是原始类型了,那就不需要转换了
  2. 调用 x.valueOf(),如果转换为基础类型,就返回转换的值
  3. 调用 x.toString(),如果转换为基础类型,就返回转换的值
  4. 如果都没有返回原始类型,就会报错

模块化

优点

  1. 解决命名冲突
  2. 提供复用性
  3. 提高代码可维护性

手段:

  1. 立即执行函数
  2. AMD CMD
  3. CommonJS
  4. 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
}