分类 Javascript 下的文章

source map 还原js报错

最近在做前端全链路监控,其中一个功能就是根据sdk上报的错误信息利用source map进行还原

上报信息类似这样

{ 
  file: '../../node_modules/downloadjs/download.js',
  message: 'Uncaught ReferenceError: data is not defined',
  line: 1,
  column: 200,
 }

包括报错信息,所在行列,然后就希望可以通过源码的source map 还原成这样子
iShot_2024-05-24_09.52.45.png

思路是使用mozilla的source-map https://github.com/mozilla/source-map

- 阅读剩余部分 -

canvas指纹生成


<script>
  const getDeviceInformation = () => {
    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform,
      screenWidth: window.screen.width,
      screenHeight: window.screen.height,
    };
  };

  function sha256(hex) {
    return crypto.subtle
      .digest("SHA-256", new TextEncoder().encode(hex))
      .then((buffer) => {
        return Array.prototype.map
          .call(new Uint8Array(buffer), (x) =>
            ("00" + x.toString(16)).slice(-2)
          )
          .join("");
      });
  }

  const bin2hex = (base64) => {
    var raw = base64;
    console.log(raw);
    var hex = "";
    for (var i = 0; i < raw.length; i++) {
      var charCode = raw.charCodeAt(i).toString(16);
      hex += charCode.length === 1 ? "0" + charCode : charCode;
    }

    return hex;
  };
  const getFingerprintId = async (content, options = {}) => {
    if (!content) {
      console.error("content is empty");
      return null;
    }
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    // 如果不存在,则返回空值,说明不支持Canvas指纹
    if (!ctx) return null;

    const txt = content || "geekbang";
    ctx.textBaseline =
      options && options.textBaseline ? options.textBaseline : "top";
    ctx.font = options && options.font ? options.font : "14px 'Arial'";

    ctx.fillStyle =
      options && options.reactStyle ? options.reactStyle : "#f60";
    // 先画一个60x20矩形内容
    ctx.fillRect(125, 1, 60, 20);

    ctx.fillStyle =
      options && options.contentStyle ? options.contentStyle : "#069";
    // 把字填充到矩形内
    ctx.fillText(txt, 2, 15);

    const b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
    const bin = atob(b64);
    const crc = bin2hex(bin.slice(-16, -12));

    const hash = await sha256(crc + JSON.stringify(getDeviceInformation()));

    document.write("<p>SHA-256 哈希值为: " + hash + "</p>");

    return hash;
  };

  window.onload = () => getFingerprintId("abc");
</script>

关于JavaScript预解析的一些理解

昨天一个师弟面试遇到一道题,对于输出的结果不太理解,问我为什么是这样,题目如下

console.log(a);
var a = 1;
console.log(a);
function a() {
    console.log(2);
}
console.log(a);
var a = 3;
console.log(a);
function a() {
    console.log(4);
}
console.log(a);

上面代码运行输出的结果是

- 阅读剩余部分 -

ES6(七)--class的继承

关键字extends

在ES6下,class的继承可以通过关键字extends实现,比如

class A {
    constructor(a) {
        console.log(a);
    }
}

class B extends A {}

new A("aaa");//aaa
new B("aaa");//aaa

1.上面定义了一个a类,b类使用关键字extends继承了a类所有的属性和方法。b类此时没有定义任何方法,也就是说b类把a类复制了一遍,所以new a("aaa")new b("aaa")结果完全一样

2.a类的constructor方法就是a的构造函数

3.如果类本身不需要接收参数,那么可以省略构造函数,当省略了构造函数,这个constructor函数会自动添加

- 阅读剩余部分 -

ES6(六)--class的基本使用

js的传统方法是通过构造函数,定义并生成新对象,是一种基于原型的面向对象系统,在ES6中新增了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象。

生成实例对象的传统方法

const Obj = function (a, b) {
    this.a = a;
    this.b = b;

    return this;
}

Obj.prototype = {
    constructor: Obj,
    print: function () {
        console.log(this.a + " " + this.b);
    }
}

new Obj(1, 2).print();//1 2

- 阅读剩余部分 -

ES6(五)--iterator和for-of循环

什么是Iterator

Iterator是一种接口,为不同的数据结构提供统一的访问机制。任何数据结构只要部署了Iterator接口,就可以完成遍历,而且这种遍历操作是依次遍历该数据结构的所有成员

Iterator遍历器的作用

1.为各种数据结构提供一个统一的,简便的访问接口

2.使得数据结构的成员能够按照某种次序排列

3.ES6新增的遍历for...of循环,Iterator接口主要供for...of消费

- 阅读剩余部分 -

ES6(四)--数据结构Map

Map是键值对的集合,类似于对象,当时键的范围不限于字符串,各种类型的值,包括对象都可以当做键。也就是说Object结构提供了“字符串-值”的对应,Map结构提供了“值-值”的对应,是一种更完善的Hash结构。

创建一个Map

const map = new Map([
    ["a", 1],
    ["b", 2]
]);

- 阅读剩余部分 -

ES6(二)--变量的解构赋值

解构赋值本质上是一种匹配模式,只要两边的模式相同,那么左边的变量就可以被赋予对应的值

数组的解构赋值

ES5中,给多个变量赋值可能是这样

var a = 1, b = 2, c = 3;
//或者这样
var a = 1;
var b = 2;
var c = 3;

- 阅读剩余部分 -