js 知识点

var和let的区别

let、const和var的区别主要体现在变量作用域、变量提升、变量重复声明、变量赋值等方面。
变量作用域 var定义的变量具有函数作用域。let 和 const定义的变量又块级作用域。只在当前代码块内有效。
变量提升 var声明的变量存在变量提升 let 和const 定义的变量不存在变量提升
变量重复声明 var声明的变量允许变量重复声明 let 和const 定义的变量不存在变量重复声明
变量赋值 const声明的变量是常量,一旦赋值就不能修改,如果尝试修改会抛出TypeError错误;let和var声明的变量可以被重新赋值。

在ES6中,全局变量从全局对象window中脱离,但是为了保持兼容性,旧的不变,所以var、function声明的全局变量依然可以在window对象上看到,而let、const声明的全局变量在window对象上看不到,在script中形成了一个块级作用域,这样在全局就可以访问到

全局变量的声明
第一种声明方式:使用var关键字+变量名在函数外部声明就是全局变量,例如:
第二种声明方式:没有使用var关键字声明,直接给变量名赋值,不管是在函数内部还是外部都是全局变量

slice与substring的区别

slice与substring同为截取字符串的一部分,也同样有两个参数。下面来描述一下slice和substring的两个参数的使用方法如下:
1、slice:两个参数分别表示截取字符串的起始位置和结束位置,如果大于0,则从前面计数,如果小于0,则从后面计数,如果省略第二个参数,则会截取到字符串的尾部,参照下面的示例更容易理解:

var s = "hello ECMAScript5.1 and ECMAScript2015";
	console.log(s.slice(6,19)); //ECMAScript5.1
	console.log(s.slice(6,-4)); //ECMAScript5.1 and ECMAScript
	console.log(s.slice(-14,-4)); //ECMAScript
	console.log(s.slice(0,-14)); //hello ECMAScript5.1 and
	console.log(s.slice(-14)); //ECMAScript2015

2、substring:两个参数分别表示字符串的起始位置和结束位置,所不同的是substring中如果结束位置在起始位置之前,则会自动将其调换后截取,当参数小于0 时按0处理,如果省略第二个参数,则会截取到字符串的尾部,参照下面的示例更容易理解:

var w = "www.excelib.com";
	console.log(w.substring(4,11)); //excelib
	console.log(w.substring(11,4)); //excelib
	console.log(w.substring(3,-4)); //www  (参数小于0 时按0处理)
	console.log(w.substring(3,0)); //www
	console.log(w.substring(4)); //excelib.com

区别
1、substring:两个参数会比较大小来判断哪一个是起始位参数哪一个是结束位置参数,通俗的讲就是小的一个数会作为起始 位置参数,大的一个数会作为结束位置参数;
slice:则不会有这样的规则,只遵循大于0,从前面计数,小于0,从后面计数的原则。
2、substring:除了两个参数会比较大小调换位置外,还满足小于0时按0处理的规则;
slice:则是根据大于0和小于0来判断计数的前后顺序

注意已废弃的 subStr(str, pos, len) 第三个参数是需要截取字符串的长度

事件捕获和冒泡,

点击父元素,(父子同事@click监听)为啥子类没监听到,因为传播机制是从window - 事件目标- window, 点击父元素,父元素事件目标,事件传播到它,捕获阶段执行完了,开始执行目标阶段,然后是冒泡阶段
. 冒泡是从里往外冒,捕获是从外往里捕。
​ 1. 当捕获存在时,先从外到里的捕获,剩下的从里到外的冒泡输出。

addEventLinster 的第三个参数 bool,用来控制,事件是在冒泡阶段还是捕获阶段监听,
同理 vue的@click默认也是在冒泡阶段监听,如需监听捕获阶段需要.caputur 修饰符。

阻止事件流

在一些情况下需要阻止事件流的传播,阻止默认动作的发生。

  • event.preventDefault():阻止默认事件。比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了。但不会阻止事件的传播。
  • event.stopPropagation():阻止捕获和冒泡阶段中当前事件的进一步传播。但是,它不能防止任何默认行为的发生。
    • 一般来说,如果只希望事件只触发在目标上,这时候可以使用 stopPropagation来阻止事件的进一步传播。通常我们认为 stopPropagation 是用来阻止事件冒泡的,其实该函数也可以阻止捕获事件。(阻止事件捕获了,事件就不向下传递了?)
  • event.stopImmediatePropagation:阻止事件冒泡,还能阻止该事件目标执行别的注册事件。
    return false:同时阻止事件冒泡也会阻止默认事件。

f123

addEventListener,接收3个参数

第一个参数event:监听的事件名称
第二个参数是函数:需要执行的事件
第三个参数是useCapture(变量):用来判断事件监听是在捕获阶段还是冒泡阶段

第三个参数为userCapyure时
1)当useCapture为true的时候是在捕获阶段触发事件 (捕获事件触发顺序是由父到子)

2)当useCapture为false的时候是在冒泡阶段触发事件(默认为false)(冒泡事件触发顺序是由子到父)

3)第三个参数不一定是 bool 值,也可以是个对象,它提供了更多选项

once:只执行一次。
passive:承诺此事件监听不会调用 preventDefault,这有助于性能。
useCapture:是否捕获(否则冒泡)。

冒泡与捕获

事件的传播机制是,捕获阶段,目标阶段,冒泡阶段

虽然传播机制里有三个截断,但是我们时间监听时候只能监听冒泡阶段或者是捕获阶段。

冒泡是从里往外冒,捕获是从外往里捕。
​ 1. 当事件监听有监听捕获阶段存在时,先从外到里的捕获,剩下的从里到外的冒泡输出。

父子dom都监听冒泡事件,为啥子dom没监听到,因为传播机制是从window - 事件目标- window, 点击父元素,父元素是事件目标,事件传播到它(事件目标),捕获阶段执行完了,开始执行目标阶段,然后是冒泡阶段

正则的使用

"12387159951"replace(/\B(?=(\d{3})+(?!\d))/g, ',')
?=p,表示位置匹配,如果后面还有表达式,那下面表达式匹配的地方是p后面的

千分位同事保留两位小数

(12345).toLocaleString('zh-CN', {style: 'currency', currency: 'CNY', minimumFractionDigits:2 })  // "¥12,345.00"
 
(12345.6789).toLocaleString('zh-CN', {style: 'currency', currency: 'CNY', minimumFractionDigits:2 })   // "¥12,345.68"
 
(12345).toLocaleString('zh-CN', {minimumFractionDigits:2 })  // "12,345.00"
 
(12345.6789).toLocaleString('zh-CN', {minimumFractionDigits:2 })   // "12,345.68"

js中的"~~“和”|"

~~ (取整)
~~代表双非按位取反运算符,

如果你想使用比Math.floor()更快的方法,那就是它了。

需要注意,对于正数,它向下取整;对于负数,向上取整;非数字取值为0,它具体的表现形式为:

~~null;      // => 0
~~undefined; // => 0
~~Infinity;  // => 0
--NaN;       // => 0
~~0;         // => 0
~~{};        // => 0
~~[];        // => 0
~~(1/0);     // => 0
~~false;     // => 0
~~true;      // => 1
~~1.9;       // => 1
~~-1.9;      // => -1

| (取整)

1.2|0  // 1
1.8|0 // 1
-1.2|0 // -1

JSON.stringify 序列化情况

这里要注意:stringily对data里的数据类型有一些要求:

  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
    就是不能保证hash结构的顺序是按照定义输出
JSON.stringify({x: 5, y: 6});  
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
    undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。
var obj = {"undefined":undefined,"func":function(){},"symbol":Symbol("")};
JSON.stringify(data); //"{}"

var arr = [undefined,Symbol(""),function(){}];
JSON.stringify(arr); //[null,null,null]
  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
JSON.stringify({[Symbol("foo")]: "foo"});   //'{}'      
  • 不可枚举的属性会被忽略
  • 对象中有时间类型的时候,序列化之后会变成字符串类型
  • 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'

两种国际时间标准:ISO8601 与 RFC2822

ISO8601,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》,规定了国际标准日期与时间表示法。
只使用数字为基本格式。使用短横线"-"间隔开年、月、日为扩展格式。
每个日期和时间值都有一个固定的位数,必须用前导零填充。
日期时间表示只能有数字或少数特殊字符组成(如“ - ”,“:”,“T”,“W”和“Z”),不允许出现地方写法,如“1月”或“星期四”等。
ISO 8601使用24小时制。HH:MM:SS.sss,HH:MM:SS,HH:MM,HH为合规的时间格式。
用字母T分隔日期和时间。如 20180703T224426Z2018-07-03T22:44:26Z
RFC2822:用于在 HTTP 和电子邮件标题等位置统一表示日期和时间的互联网信息格式。RFC 2822 包括星期几(短)、数字日期、月份的三字母缩写、年、时间和时区,显示为 Thu Mar 14 2024 12:21:40 GMT+0800
或者 YYYY/MM/DD HH:MM:SS ± timezone(时区用4位数字表示) 这种格式是RFC2822 的数字形式表达

sessionStorage和localStorage

sessionStorage和localStorage的value中储存的数据为JSON.stringify(null)序列化过的,所以存null 取得话其实是 ‘null’

Window和window 区别

Window 是接口, window 是实例,全局变量是 window 的属性。

前端js没有有办法拦截到重定向请求

Map 与 weakMap 的区别

键类型的限制:在Map中,键可以是任意类型的值(包括基本类型和对象引用),而在WeakMap中,键只能是对象引用。这是因为WeakMap的键是弱引用,不会阻止对象被垃圾回收,使得WeakMap更适合于存储对象之间的关联信息。
垃圾回收机制:在Map中,如果某个键不再被引用,它仍然会被Map引用,并且不会被垃圾回收。而在WeakMap中,如果某个键不再被引用,它会被自动从WeakMap中删除,这也是WeakMap的一个特性,可以避免内存泄漏。
迭代:在Map中,可以使用Map.prototype.keys()、Map.prototype.values()和Map.prototype.entries()等方法来迭代Map中的键、值或键值对,而在WeakMap中,由于键是对象引用,无法直接迭代键或值。
功能:Map相比WeakMap提供了更多的功能,比如可以获取Map的大小(使用Map.prototype.size属性),可以通过键获取值(使用Map.prototype.get()方法),可以遍历Map中的键值对等。而WeakMap相对简单,只提供了WeakMap.prototype.get()、WeakMap.prototype.set()、WeakMap.prototype.has()和WeakMap.prototype.delete()等基本操作。

综上所述,Map适用于一般的键值对存储需求,而WeakMap更适用于需要存储对象关联信息且不希望干扰垃圾回收的场景。

promise的reject控制台报错

状态为reject且控制台报错,但是在then里写上rejected状态的回调函数后,浏览器就不会报错了
据说只有chrome会报错,其他浏览器的出现的错误不会被捕获,也不会传递到外层代码,最后没有任何输出,promise的状态也变为rejected

promise的finally 回调不执行问题

一般来说无论promise的最后的状态,在执行完then或者catch指定的回调函数后,都会执行finall方法指定的回调函数,它防止then和catch回调里的代码重复,但是需要注意的是,如果我们在promiseh函数中,没有使用resolve函数或者rejecte函数,也就是promised的状态还为初始状态“padding”,那么finally回调不会执行,同时then回调和catch回调也不会执行

promise的resolve 或者reject执行后 函数不会结束执行

promise的resolve 或者reject执行后,所在的函数不会结束执行,只是promise的状态改变了,需要手动return

get() 和 set()

出现在两类地方

  • 出现普通对象里,
  • 出现在class中
  • 出现在defineProperty

前两种需在函数后 加上 指定的属性名,后者因为出现在defineProperty(给对象定义某一个属性)所以已经指定属性名了,不需要再加了。

let obj = {
  a: '吕小布',
  get b() {
    console.log('一旦调用对象的b属性,就会触发b属性的get方法')
  },
  set b(newVal) {
    b = newVal
    console.log('调用了b属性的set方法,方法的值是:' + newVal)
  }
let obj = {}
    Object.defineProperty(obj, "aa", {
      set: function (v) {
        console.log("set执行了!!!");
        obj["aa"] = v
      },
      get: function () {
        console.log("get执行了!!!");
        return "12-01283"
      }
    })
    class Ert {
      constructor() {
        //this.age = age;
      }

      sayHellp() {
        return "hgello"
      }
      get() {
        return "[][]]]" //这种没有指明的 get方法 不会添加属性
      }
      get age() { //这种get 后面写上具体属性(比如age)的话 会给类的 this 绑定上这个属性(age)。
        return "222"
      }
      set age(newV) {
        console.log(newV, "set" + newV);
      }
    }

JS中 for循环的终止循环 return break continue 的区别

return语句的作用是指定函数返回的值。return语句只能出现在函数体内,出现在代码中的其他任何地方都会造成语法错误!用return语句来终止一个函数的执行。

return (终止循环并且退出循环所在的方法)

function add(){
  let list = [1,2,3,4]
  for(var i=0;i<list.length;i++){
    if(i === 2)return;
    console.log(list[i]);  // 1 2
  }
}
add()

continue-终止本次循环。(终止当前循环,进行下一次循环)

for (let i = 1; i < 5; i++) { 
    if (i === 2) { 
        continue; 
    } 
    console.log(i)  // 1 3 4
}

break-完全结束循环 (终止循环执行循环体下面的代码)

for (let i = 1; i < 5; i++) { 
    if (i === 2) { 
        break; 
    } 
    console.log(i)  // 1
}

【JavaScript】js.map 文件的意义

source map 文件是 js 文件压缩后,文件的变量名替换对应、变量所在位置等元信息数据文件,一般这种文件和 min.js 主文件放在同一个目录下。 比如压缩后原变量是 map,压缩后通过变量替换规则可能会被替换成 a,这时 source map 文件会记录下这个 mapping 的信息,这样的好处就是说,在调试的时候,如果有一些 JS 报错,那么浏览器会通过解析这个 map 文件来重新 merge 压缩后的 js,使开发者可以用未压缩前的代码来调试,这样会给我们带来很大的方便!

数组去重

  1. 利用es6的 set
 let array = [1, 2, 2, 3, 4, 4, 5];
 let uniqueArray = [...new Set(array)];
  1. 利用filter结合IndexOf
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = array.filter((item, index) => array.indexOf(item) === index);
  1. 使用 reduce 方法
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = array.reduce((accumulator, currentValue) => {
    if (!accumulator.includes(currentValue)) {
        accumulator.push(currentValue);
    }
    return accumulator;
}, []);

浏览器知识

  1. 每个浏览器里单独的tab就是一个单独的window窗口
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值