JavaScript 知识总结下篇(更新版)

91.实现一个 promise

参考链接:实现一个完美符合Promise/A+规范的Promise · Issue #4 · forthealllight/blog · GitHub

function myPromise(constructor) {
    let self = this;
    self.status = "pending" // 定义状态改变前的初始状态
    self.value = undefined;// 定义状态为resolved的时候的状态
    self.reason = undefined;// 定义状态为rejected的时候的状态
    function resolve(value) {
        // 两个 === "pending",保证了状态的改变是不可逆的
       if(self.status === "pending") {
          self.value = value;
          self.status = "resolved";
       }
    }
    function reject(reason) {
        // 两个 === "pending",保证了状态的改变是不可逆的
       if(self.status === "pending") {
          self.reason = reason;
          self.status = "rejected";
       }
    }
    // 捕获构造异常
    try {
       constructor(resolve, reject);
    }
    catch(e) {
       reject(e);
    }
}
// 在myPromise的原型上定义链式调用的then方法
myPromise.prototype.then = function(onFullfilled, onRejected) {
   let self = this;
   switch(self.status) {
      case "resolved":
        onFullfilled(self.value);
        break;
      case "rejected":
        onRejected(self.reason);
        break;
      default:       
   }
}

 92.Function.proto(getPrototypeOf)

获取一个对象的原型,在 chrome 中可以通过proto的形式,或者在 ES6 中可以通过 Object.getPrototypeOf 的形式。

Function.proto 说明 Function 由什么对象继承而来:

Function.__proto__ == Object.prototype;   // false
Function.__proto__ == Function.prototype; // true

说明 Function 的原型也是 Function

93.数组常用方法

push() 和 unshift():向数组的 尾部/头部 添加若干元素,并返回 数组的 新长度;

var arr = [1, 2];
// 向末尾追加元素
arr.push(3, 4);         // arr = [1,2,3,4];
// 向开头追加元素
arr.unshift(6, 7);    // arr = [6,7,1,2,3,4];

pop() 和 shift():从数组的 尾部/头部 删且只删1个元素;空数组是继续删除,且不报错,返回undefined

// 删除末尾元素
arr.pop();      // arr = [6,7,1,2,3];
// 删除开头元素
arr.shift();      // arr = [7,1,2,3]

splice() 方法用于添加或删除数组中的元素,会改变原始数组。

slice() 方法可从已有的数组中返回选定的元素,可提取字符串的某个部分,并以新的字符串返回被提取的部分,不会改变原始数组。

94.数组去重

参考文章:JavaScript中数组去重的几种方法(双循环去重、indexOf去重、相邻元素去重、对象属性去重、set与解构赋值去重、set与Array.form去重)_indexof循环去重_谁是听故事的人的博客-CSDN博客

1.indexOf 循环去重:

返回某个指定的元素在数组中首次出现的位置:定义一个空数组res,调用 indexOf() 方法对原来的数组进行遍历,如果元素不在res中,将其 push 进res中,最后将res返回即可获得去重的数组(判断新数组中是否有a[i],如果没有indexOf,返回-1,把a[i]放入新数组中)

var res = []
for (var i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) == -1) {
        res.push(arr[i]);
    }
}
return res;

2.ES6 Set 去重:

var newArr = Array.from(new Set(arr));

3.Object 键值对去重:

把数组的值存成 Object 的 key 值,比如 Object[val1] = true, 在判断另一个值的时候,如果 Object[val2] 存在,说明该值重复

95.去除字符串首尾空格

使用正则(^\s)|(\s$)

96.性能优化

通过 减少 HTTP 请求;使用内容发布网络(CDN);添加本地缓存;压缩资源文件;将 CSS 样式表放在顶部;把 javascript 放在底部(浏览器的运行机制决定);避免使用 CSS 表达式;减少 DNS 查询;使用外部 javascript 和 CSS;避免重定向;图片懒加载等。

97.跨域的原理

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 js 实施的安全限制,只要协议、域名、端口有任一不同,都被当作不同的域。

98.如何解决跨域

1. CORS(跨域资源共享):在服务器端配置CORS,允许特定域名的请求访问您的资源。通过设置适当的响应头,控制跨域请求的访问权限。

2. JSONP:使用JSONP允许从不同域名获取数据。但JSONP只适用于GET请求,可能存在安全风险。

3. 代理服务器:在服务器上设置一个代理,将跨域请求转发到目标服务器,然后将响应返回给客户端。

4. WebSocket:如果需要实时通信,WebSocket是一种可以跨域的双向通信协议。

5. 服务器配置:调整服务器配置,使请求绕过跨域限制(如在Nginx或Apache上设置反向代理)。

6. 使用跨域库:使用JavaScript库(如axios)提供了简化处理跨域请求的方法。

99.暂停死区

在代码块内,使用 let、const 命令声明变量之前(没有变量提升),该变量都是不可用的。

100.游戏《Flappy Bird》

一只小鸟在飞,前面是无尽的沙漠,上下不断有钢管生成,要躲避钢管。在玩这个游戏时总出现卡顿甚至崩溃,其原因以及解决办法:

这是单机游戏,回答与网络无关

1.内存溢出问题:在钢管离开可视区域后,销毁钢管;不断生成钢管且不及时清理,容易内存溢出从而游戏崩溃,因此可通过垃圾收集器回收钢管。

2.资源过大问题:选择图片文件更小的图片格式,比如 webp、png 格式,因为绘制图片需要较大计算量。

3.资源加载问题:在可视区域之前预加载好资源,如果在可视区域生成钢管的话,用户认为钢管是卡顿后才生成的,用户体验不流畅。

4.canvas 绘制频率问题:大部分显示器刷新频率为 60 次/s,因此游戏的每一帧绘制间隔时间需要小于 1000/60=16.7ms,才能实现不卡顿。

101.按需加载

当用户触发了动作时才加载对应的功能。触发的动作要看具体的业务场景,包括但不限于:鼠标点击、输入文字、拉动滚动条,鼠标移动、窗口大小更改等。加载的文件可以是 JS、图片、CSS、HTML 等。

102.什么是 virtual dom(虚拟dom)

用 JavaScript 对象结构表示 DOM 树的结构,用这个树构建一个真正的 DOM 树,插到文档中, 当状态变更的时候,重新构造一棵新的对象树。将新树和旧树比较,记录差异,应用到所构建的真正 DOM 树中,从而实现视图更新。Virtual DOM 本质上是在 JS 和 DOM 之间做一个缓存。

103.Promise 回调链

Promise 能够在回调函数里使用 return 和 throw, 所以在 then 中可以 return 出一个 promise 对象或其他值,也可以 throw 出一个错误对象;如果没有 return,将默认返回 undefined,后面的 then 中的回调参数接收到的是 undefined。

104.promise 和 await/async 的关系

"异步" 用于描述在执行代码时不会阻塞程序的其他操作。当一个操作被标记为异步时,程序可以继续执行其他任务,而不必等待该操作完成。

"async" 是在JavaScript中定义异步函数的关键字。异步函数返回一个 Promise 对象,可以使用 "await" 关键字来等待异步操作的完成。

"Promise" 是 JavaScript 中用于处理异步操作的对象。它表示一个可能会在未来完成的值或错误。Promise 有三种状态:等待(pending)、已解决(fulfilled)和已拒绝(rejected)。当 Promise 被解决或拒绝时,它会调用相应的回调函数,允许在异步操作完成后执行相关操作。

以下是一个使用异步函数和 Promise 的示例:

async function fetchData() {
  try {
    const response = await fetch('https://api.exaPromise.com/data');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw error;
  }
}

fetchData()
  .then(data => {
    console.log('Fetched data:', data);
  })
  .catch(error => {
    console.error('Error:', error);
  });

在上面的示例中,`fetchData` 是一个异步函数,它使用 "await" 关键字来等待异步操作(fetch 请求和 JSON 解析)的完成。该函数返回一个 Promise,使用 `.then()` 来处理解决的 Promise 或使用 `.catch()` 来处理拒绝的 Promise。

105.ES6,ES7 的语法

ES6 语法特性:

1. 箭头函数:简化了函数的书写,同时固定了函数内部的上下文。

2. let 和 const 声明:引入了块级作用域的变量声明,取代了之前的 var 声明。

3. 解构赋值:可以从对象或数组中提取值,并将它们赋值给变量。

4. 模板字符串:使用反引号(`)创建字符串,可以在其中插入变量或表达式。

5. 类:引入了基于原型的面向对象编程的类语法。

6. Promise:引入了用于处理异步操作的 Promise 对象。

7. 默认参数:在函数声明中可以为参数设置默认值。

8. 展开操作符(拓展运算符):用于在数组或对象字面量中展开数组或对象。

9. 迭代器和生成器:提供了更灵活的迭代和异步编程模型。

ES7 语法特性:

1. 指数操作符:使用双星号(**)进行指数运算。

2. Array.prototype.includes() 方法:用于判断数组中是否包含某个元素。

3. async/await:用于更简洁地处理异步操作,使异步代码看起来更像同步代码。

4. Object.values() 和 Object.entries() 方法:用于获取对象的值数组和键值对数组。

5. String.prototype.padStart() 和 String.prototype.padEnd() 方法:用于填充字符串到指定长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为何幸福如驴薄饼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值