不知道是什么东西
new操作符的实现原理
- 首先创建了一个新的空对象
- 设置原型,将对象的原型设置为函数的 prototype对象。
- 让函数的 this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
- 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
function objectFactory() { let newObject = null; let constructor = Array.prototype.shift.call(arguments); let result = null; // 判断参数是否是一个函数 if (typeof constructor !== "function") { console.error("type error"); return; } // 新建一个空对象,对象的原型为构造函数的 prototype 对象 newObject = Object.create(constructor.prototype); // 将 this 指向新建对象,并执行函数 result = constructor.apply(newObject, arguments); // 判断返回对象 let flag = result && (typeof result === "object" || typeof result === "function"); // 判断返回结果 return flag ? result : newObject; } // 使用方法 objectFactory(构造函数, 初始化参数);
map和weakMap的区别???
JavaScript 类数组对象的定义?
  一个拥有 length 属性和若干索引属性的对象就可以被称为类数组对象,类数组对象和数组类似,但是不能调用数组的方法。常见的类数组对象有 arguments 和 DOM 方法的返回结果。
  arguments 是一个对象,它的属性是从 0 开始依次递增的数字,还有length等属性,与数组相似;但是它却没有数组常见的方法属性,如forEach, reduce等,所以叫它们类数组。
类数组转换为数组的方法:
- Array.from(arrayLike);
- Array.prototype.slice.call(arrayLike);
- Array.prototype.splice.call(arrayLike, 0);
- Array.prototype.concat.apply([], arrayLike);
遍历类数组的方法:
// 可以使用call和apply方法 function foo(){ Array.prototype.forEach.call(arguments, a => console.log(a)) } // Array.from方法将类数组转化成数组 function foo(){ const arrArgs = Array.from(arguments) arrArgs.forEach(a => console.log(a)) } // 展开运算符将类数组转化成数组 function foo(){ const arrArgs = [...arguments] arrArgs.forEach(a => console.log(a)) }
数组的原生:
- 转换为字符串:toString()、toLocalString()、join()
- 数组尾部操作的方法 pop() 和 push()。
- 数组首部操作的方法 shift() 和 unshift()
- 数组连接的方法 concat() ,返回的是拼接好的数组,不影响原数组。
- 数组截取办法 slice(),用于截取数组中的一部分返回,不影响原数组。
- 数组插入方法 splice(),影响原数组查找特定项的索引的方法
- indexOf() 和 lastIndexOf()
- 迭代方法 every()、some()、filter()、map() 和 forEach() 方法
- 数组归并方法 reduce()
什么是 DOM 和 BOM?
  DOM: 指的是文档对象模型,是把文档当做一个对象,这个对象主要定义了处理网页内容的方法和接口。
  BOM: 指的是浏览器对象模型,是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的方法和接口。BOM的核心是 window,window 对象含有 location 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象。
escape、encodeURI、encodeURIComponent 的区别
  encodeURI: 是对整个 URI 进行转义,将 URI 中的非法字符转换为合法字符,所以对于一些在 URI 中有特殊意义的字符不会进行转义。
encodeURIComponent: 是对 URI 的组成部分进行转义,所以一些特殊字符也会得到转义。
  escape 和 encodeURI: 的作用相同,不过它们对于 unicode 编码为 0xff 之外字符的时候会有区别,escape 是直接在字符的 unicode 编码前加上 %u,而 encodeURI 首先会将字符转换为 UTF-8 的格式,再在每个字节前加上 %。
AJAX的理解,实现一个AJAX请求
  AJAX 指的是通过 JavaScript 的 异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。
创建AJAX请求的步骤:
- 创建一个 XMLHttpRequest对象。
- 在这个对象上使用 open方法创建一个HTTP请求
- 添加请求头和状态监听方法 ,XMLHttpRequest对象一共有5个状态,当它的状态变化时会触发onreadystatechange事件
- send请求
const SERVER_URL = "/server"; let xhr = new XMLHttpRequest(); // 创建 Http 请求 xhr.open("GET", url, true); // 设置状态监听函数 xhr.onreadystatechange = function() { if (this.readyState !== 4) return; // 当请求成功时 if (this.status === 200) { handle(this.response); } else { console.error(this.statusText); } }; // 设置请求失败时的监听函数 xhr.onerror = function() { console.error(this.statusText); }; // 设置请求头信息 xhr.responseType = "json"; xhr.setRequestHeader("Accept", "application/json"); // 发送 Http 请求 xhr.send(null);
使用Promise封装AJAX:
// promise 封装实现: function getJSON(url) { // 创建一个 promise 对象 let promise = new Promise(function(resolve, reject) { let xhr = new XMLHttpRequest(); // 新建一个 http 请求 xhr.open("GET", url, true); // 设置状态的监听函数 xhr.onreadystatechange = function() { if (this.readyState !== 4) return; // 当请求成功或失败时,改变 promise 的状态 if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; // 设置错误监听函数 xhr.onerror = function() { reject(new Error(this.statusText)); }; // 设置响应的数据类型 xhr.responseType = "json"; // 设置请求头信息 xhr.setRequestHeader("Accept", "application/json"); // 发送 http 请求 xhr.send(null); }); return promise; }
JavaScript为什么要进行变量提升,有什么问题?
  变量提升的表现是,无论在函数中何处位置声明的变量,好像都被提升到了函数的首部,可以在变量声明前访问到而不会报错。
  造成变量声明提升的本质原因是 js 引擎在代码执行前有一个解析的过程,创建了执行上下文,初始化了一些代码执行时需要用到的对象。当访问一个变量时,会到当前执行上下文中的作用域链中去查找
  首先要知道,JS在拿到一个变量或者一个函数的时候,会有两步操作,即解析和执行。
解析: JS会检查语法,并对函数进行预编译。解析的时候会先创建一个全局执行上下文环境,先把代码中即将执行的变量、函数声明都拿出来,变量先赋值为undefined,函数先声明好可使用。在一个函数执行之前,也会创建一个函数执行上下文环境,跟全局执行上下文类似,不过函数执行上下文会多出this、arguments和函数的参数。
执行: 就是按照代码的顺序依次执行。
  变量提升的两个原因:提高性能 容错性更好
ES6模块与CommonJS模块有什么异同?
  CommonJS 是社区规范, ES6 Module 是官方后出的规范
- CommonJS模块输出的是一个值的拷贝,- ES6 Module输出的是值的引用
- CommonJS模块是运行时加载,- ES6 Module是编译时输出接口。
- CommonJS是单个值导出,- ES6 Module可以导出多个
- CommonJS是动态语法可以写在判断里,- ES6 Module静态语法只能写在顶层
- CommonJS的 this 是当前模块,- ES6 Module的 this 是 undefined
React的 setState 同步还是异步
  setState 本身代码的执行肯定是同步的,这里的异步是指是多个 state 会合成到一起进行批量更新。 同步还是异步取决于它被调用的环境。
- 如果 setState在 React 能够控制的范围被调用,它就是异步的。比如合成事件处理函数,生命周期函数, 此时会进行批量更新,也就是将状态合并后再进行 DOM 更新。
- 如果 setState在原生 JavaScript 控制的范围被调用,它就是同步的。比如原生事件处理函数,定时器回调函数,Ajax 回调函数中,此时setState被调用后会立即更新 DOM 。
对函数式编程的理解
函数式编程有两个核心概念
- 数据不可变(无副作用): 它要求你所有的数据都是不可变的,这意味着如果你想修改一个对象,那你应该创建一个新的对象用来修改,而不是修改已有的对象。
- 无状态: 主要是强调对于一个函数,不管你何时运行,它都应该像第一次运行一样,给定相同的输入,给出相同的输出,完全不依赖外部状态的变化。
纯函数带来的意义
- 便于测试和优化:这个意义在实际项目开发中意义非常大,由于纯函数对于相同的输入永远会返回相同的结果,因此我们可以轻松断言函数的执行结果,同时也可以保证函数的优化不会影响其他代码的执行。
- 可缓存性:因为相同的输入总是可以返回相同的输出,因此,我们可以提前缓存函数的执行结果。
- 更少的 Bug:使用纯函数意味着你的函数中不存在指向不明的 this,不存在对全局变量的引用,不存在对参数的修改,这些共享状态往往是绝大多数 bug 的源头。
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号