Tag:javascript
All the articles with the tag "javascript".
JS中本地对象、内置对象、宿主对象分别是什么,有什么区别?
Posted on:2024年9月22日 at 13:48在 JavaScript 中,本地对象、内置对象和宿主对象的定义和区别如下: 1. 本地对象(Native Objects) 定义:本地对象是由 JavaScript 语言本身提供的对象,不依赖于任何外部环境。 例子:Object、Array、Function、Number、String、Boolean、RegExp 等。 特点:这些对象的构造函数和方法是 JavaScript 语言标准的一部分,
JavaScript 是怎么做内存管理的?
Posted on:2024年9月19日 at 01:20JavaScript 的内存管理主要依赖于自动垃圾回收机制。以下是内存管理的几个关键点: 1. 内存分配 堆与栈:JavaScript 使用堆(Heap)和栈(Stack)两种内存区域。基本数据类型(如数字、字符串、布尔值)通常存储在栈中,而对象和数组等复杂类型则存储在堆中。 2. 垃圾回收 自动垃圾回收:JavaScript 使用垃圾回收器(Garbage Collector,GC)自动管理内存
for...in和for...of有什么区别?
Posted on:2024年9月13日 at 01:10for…of 是ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,和ES3中的for…in的区别如下: for…of 遍历获取的是 可迭代对象的键值,for…in 获取的是对象的键名(键名必须是可枚举的); for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链; 对于数组的遍历,for…
引用类型有哪些,有什么特点
Posted on:2024年9月9日 at 14:29在JavaScript中,引用类型是指非基本数据类型,它们是由对象、数组、函数等复杂数据结构组成的。 常见的引用类型包括: 对象(Object):对象是JavaScript中最基本的引用类型,它可以用来存储键值对,也可以通过原型链实现继承。 数组(Array):数组是一种有序的集合,可以存储任意类型的数据,它的长度是动态的,可以随时添加或删除元素。 函数(Function):函数是一种可执行的对象
如何拦截 web 应用的请求
Posted on:2024年9月9日 at 14:20在前端拦截和处理 Web 应用的所有请求,可以使用以下方法: 使用 Fetch 或 XMLHttpRequest:在前端代码中使用 Fetch API 或 XMLHttpRequest 对象发送请求。通过拦截 Fetch 或 XMLHttpRequest 对象的 open 和 send 方法,可以在请求发出前进行拦截和修改。这样可以捕获请求的相关信息,并进行相应的处理。 示例代码(使用 Fetch
Object 对象有哪些场景 api ?
Posted on:2024年9月9日 at 14:18关键词:Object对象api 方法/属性 描述 Object.keys(obj) 返回一个由给定对象的所有可枚举自身属性的名称组成的数组 Object.values(obj) 返回一个给定对象所有可枚举属性值的数组 Object.entries(obj) 返回一个给定对象自身可枚举属性的 [key, value] 数组 Object.assign(target, ...sources) 将一个或
实现日期格式化 format 函数
Posted on:2024年9月9日 at 14:17// js 实现日期的 format 函数 // // YYYY 对应年 // MM 对应月 // DD 对应日 // // HH 对应 24 小时制度 // hh 对应 12 小时制度 // mm 对应分钟 // ss 对应秒 const date = new Date(); const formattedDate = date.format('YYYY-MM-DD HH:mm:ss'); co
实现一个函数, 计算两个日期之间的天数差
Posted on:2024年9月9日 at 14:13以下是使用JavaScript实现计算两个日期之间的天数差的函数: function calculateDateDifference(date1, date2) { // 确保输入的日期是 Date 对象 const startDate = new Date(date1); const endDate = new Date(date2); // 计算时间差(以毫秒为单位) const timeDi
JavaScript 中, 隐藏类是什么概念?
Posted on:2024年9月9日 at 14:08JavaScript隐藏类 隐藏类是JavaScript引擎中的一种优化技术(并不是JavaScript语言中的某个类!!),用于提高对象访问的性能。隐藏类是一种数据结构,用于跟踪对象的属性和方法的布局和类型,以便在代码运行时能够快速访问它们。 当JavaScript引擎在执行代码时,会动态地创建对象的隐藏类。隐藏类会跟踪对象的属性和方法,并为它们分配固定的内存偏移量。每当对象的属性和方法发生变化
JavaScript 和 BOM、DOM 、ECMAScript、Nodejs 之间是什么关系
Posted on:2024年9月9日 at 14:03ECMAScript ECMAScript是JavaScript的标准化规范,它定义了JavaScript的语法、数据类型、函数、控制流等。ECMAScript最早在1997年发布,由欧洲计算机制造商协会(ECMA)负责制定和维护。 ECMAScript的目的是为了确保不同厂商的JavaScript实现在语法和行为方面保持一致性,以便开发者能够轻松地编写跨平台、跨浏览器的JavaScript代码。
splice 和 slice 有什么区别?
Posted on:2024年9月9日 at 14:02关键词:Array 方法 splice、Array 方法 slice、splice 和 slice 区别 splice() 和 slice() 是 JavaScript 中用于操作数组的两个方法,它们的功能和用法有一些区别。 splice() 方法: 功能:从数组中添加、删除或替换元素。 用法:array.splice(start, deleteCount, item1, item2, ...)。
什么是匿名函数?
Posted on:2024年9月9日 at 14:01匿名函数 在JavaScript中,匿名函数是一种没有名称的函数。它是一种可以直接被定义和使用的函数,而不需要通过函数名进行引用。匿名函数通常用于需要临时定义一个函数并在某个地方立即调用它的情况下使用。 匿名函数可以使用两种方式进行定义:函数表达式和箭头函数。 函数表达式: var func = function() { // 函数的代码块 }; 在上述代码中,我们定义了一个没有名称的函数,并将其
箭头函数解决了什么问题
Posted on:2024年9月9日 at 13:56箭头函数是ES6中引入的一种新的函数语法,它主要解决了以下几个问题: 简化函数表达式:箭头函数提供了一种更简洁的函数定义方式,可以用更短的语法来定义函数,减少了冗余的代码。例如,使用箭头函数可以将一个函数表达式 function(x) { return x * x; } 简化为 (x) => x * x;。 简化this的指向:在传统的函数定义中,函数内部的this指向的是调用该函数的对象。而在箭
副作用是什么概念
Posted on:2024年9月9日 at 13:56在 JavaScript 中,副作用(side effect)是指函数或表达式在执行过程中对外部环境产生的影响,而不仅仅是返回一个值。副作用可能包括但不限于对全局变量、参数、数据结构、文件系统、网络请求等进行修改。 副作用可以是有意为之,也可以是无意之间发生的。在函数式编程中,减少副作用是一种被推崇的编程风格,因为副作用使得代码的行为更难以跟踪和理解,容易引发不可预见的 bug。尽可能减少副作用有
JS 中如何实现大对象深度对比
Posted on:2024年9月9日 at 13:47关键词:JS对象对比 在JavaScript中,可以使用递归的方式实现大对象的深度对比。以下是一个示例函数,用于比较两个大对象的每个属性是否相等: function deepEqual(obj1, obj2) { // 检查是否为同一个引用 if (obj1 === obj2) return true; // 检查类型 if (typeof obj1 !== 'object' || obj1 ==
Js 中,有哪些方法可以退出循环
Posted on:2024年9月9日 at 01:24一般使用以下几种方法退出循环: 1. break 作用:立即终止当前循环,跳出循环体并继续执行循环后的代码。 用法:通常在循环内的条件判断中使用。 示例:for (let i = 0; i < 10; i++) { if (i === 5) { break; // 退出循环 } console.log(i); // 输出 0, 1, 2, 3, 4 } 2. return 作用:用于函数中,立即退
for...of、for...in、for 循环, 三者有什么区别?
Posted on:2024年9月9日 at 01:19for...of、for...in 和 for 是 JavaScript 中用于循环的三种不同结构,每种结构有不同的用途和特性。 1. for 循环 作用:最基本的循环结构,可以用于遍历数组、对象等。 用法:需要初始化变量、设置循环条件和更新变量。 示例: for (let i = 0; i < 5; i++) { console.log(i); // 输出 0, 1, 2, 3, 4 } 特点:
onpopstate 可以监听到 pushstate 的事件吗?
Posted on:2024年9月3日 at 01:22onpopstate 事件无法直接监听到 pushState 或 replaceState 方法的调用。这是因为 pushState 和 replaceState 方法本身不会触发 popstate 事件,它们只是修改浏览器的历史记录和 URL。 popstate 事件的触发条件 popstate 事件只会在以下情况下触发: 用户通过浏览器的前进或后退按钮进行导航。 用户点击浏览器的历史记录(例如
原生 js 如何进行监听路由的变化?
Posted on:2024年9月3日 at 01:20在原生 JavaScript 中,可以使用以下方法来监听路由的变化: 1. 使用 hashchange 事件 当使用 hash 路由(即 URL 中包含 # 部分)时,可以通过监听 hashchange 事件来响应路由的变化。 示例: window.addEventListener('hashchange', function() { console.log('Hash changed to:',
如何冻结一个 JS 对象?
Posted on:2024年9月2日 at 01:14可以使用 Object.freeze() 方法冻结一个 JavaScript 对象。 冻结对象会阻止对对象的修改,包括添加新属性、删除现有属性以及修改现有属性的值。 使用 Object.freeze() // 创建一个对象 const person = { name: 'Alice', age: 25 }; // 冻结对象 Object.freeze(person); // 尝试修改对象的属性 p
原型链的终点是什么?
Posted on:2024年8月23日 at 05:17原型链的终点是 Object.prototype。 在 JavaScript 中,所有对象的原型链最终都会归结到 Object.prototype,这是原型链的最后一个环节。 原型链的结构 对象实例:每个 JavaScript 对象都有一个内部属性 [[Prototype]](在代码中通过 __proto__ 或 Object.getPrototypeOf 可以访问),这个属性指向该对象的原型。
hasOwnProperty 与 instanceof 有什么区别
Posted on:2024年8月23日 at 05:15hasOwnProperty 和 instanceof 是 JavaScript 中两个用于处理对象的不同方法,它们用于不同的目的。以下是它们的主要区别和使用场景: 1. hasOwnProperty 定义:hasOwnProperty 是所有 JavaScript 对象继承自 Object 的一个方法,用于检查对象自身是否具有特定的属性(即,该属性是否是对象本身的属性,而不是继承自原型链上的属性
JS 创建对象的方式有哪些?
Posted on:2024年8月23日 at 05:13以下是创建对象的主要方法: 1. 对象字面量(Object Literal) 定义:直接使用花括号 {} 来创建对象。 示例: const person = { name: 'John', age: 30, greet() { console.log('Hello!'); } }; 特点: 语法简洁。 适合创建简单对象或用于字面量初始化。 2. 构造函数(Constructor Function)
函数声明与函数表达式有什么区别
Posted on:2024年8月22日 at 11:10函数声明(Function Declaration)和函数表达式(Function Expression)是两种定义函数的方式,在 JavaScript 中有一些重要的区别。以下是它们的主要区别和特点: 1. 函数声明(Function Declaration) 定义方式: function myFunction() { console.log('Function Declaration'); }
普通函数动态参数 和 箭头函数的动态参数有什么区别?
Posted on:2024年8月22日 at 11:09普通函数和箭头函数在处理动态参数(即不确定数量的参数)时,有一些重要的区别,主要体现在参数处理和 this 上下文的处理方式。以下是这两种函数在处理动态参数时的主要区别: 1. 普通函数的动态参数 普通函数可以使用 arguments 对象来处理不确定数量的参数。arguments 是一个类数组对象,包含了传递给函数的所有参数。 示例: function normalFunction() { co
JS 中的数组和函数在内存中是如何存储的?
Posted on:2024年8月22日 at 11:04在 JavaScript 中,数组和函数在内存中的存储方式有所不同,但它们都遵循 JavaScript 引擎的内存管理机制。以下是对数组和函数在内存中存储的详细解释: 1. 数组 内存存储: 连续内存:数组通常在内存中是以连续的内存块存储的。每个元素在内存中都有一个固定的位置,这使得可以快速访问特定索引的元素。 动态大小:JavaScript 数组是动态的,即使在创建时给定了初始大小,数组的大小也
use strict是什么,有什么用?
Posted on:2024年8月22日 at 10:58"use strict" 是 JavaScript 的严格模式声明,用于启用 ECMAScript 5 中引入的严格模式。严格模式提供了一种更严格的解析和执行 JavaScript 代码的方式,有助于提高代码的安全性和一致性。 主要功能和用途 消除 JavaScript 中的一些不安全行为: 在严格模式下,某些不安全的行为被禁止。例如,不能使用未声明的变量,防止全局变量的无意创建。 修复 Java
escape、encodeURI、encodeURIComponent 有什么区别?
Posted on:2024年8月22日 at 10:57escape、encodeURI 和 encodeURIComponent 都是 JavaScript 中用于编码 URI 组件的函数,但它们的用途和处理方式有所不同。以下是对这三者的详细解释和区别: 1. escape 描述:escape 是一个过时的函数,用于对字符串进行 URL 编码。它将非 ASCII 字符和一些特殊字符转换为百分号编码(%xx)格式。 语法:escape(string)
什么是伪数组和类数组?
Posted on:2024年8月22日 at 10:55伪数组(Pseudo-array)和类数组(Array-like)是描述具有类似数组结构的对象的术语,虽然它们并不是真正的数组。它们通常具有下列特性: 伪数组(Pseudo-array) 伪数组指的是一种对象,它看起来像数组,因为它具有索引属性和 length 属性,但并不具备数组的所有方法(如 push, pop, forEach)。伪数组的关键特征包括: 索引属性:对象的属性名是数字,通常从0
js 函数参数有默认值时,如果传递的参数是 undefined 那么会被默认值赋值吗?
Posted on:2024年8月22日 at 10:50在 JavaScript 中,如果函数参数有默认值,并且调用函数时传递的参数是 undefined,那么该参数会被赋予默认值。这是由于 JavaScript 的参数默认值机制的设计。 默认值机制 当函数参数具有默认值时,默认值机制会在以下情况下生效: 未传递参数:如果调用函数时没有提供该参数,则会使用默认值。 传递 undefined:如果显式地将 undefined 作为参数传递,默认值机制会将
说说 Javascript 为什么会存在数字精度丢失的问题,以及如何进行解决?
Posted on:2024年8月22日 at 06:21一、场景复现 一个经典的面试题 0.1 + 0.2 === 0.3 // false 为什么是false呢? 先看下面这个比喻 比如一个数 1÷3=0.33333333...... 3会一直无限循环,数学可以表示,但是计算机要存储,方便下次取出来再使用,但0.333333...... 这个数无限循环,再大的内存它也存不下,所以不能存储一个相对于数学来说的值,只能存储一个近似值,当计算机存储后再取出
typeof null 的结果是什么,为什么?
Posted on:2024年8月22日 at 04:07typeof null 的结果是 "object"。这是一个 JavaScript 的古老错误,源于语言的早期实现。 原因 历史原因: 在 JavaScript 的早期版本中,null 的内部表示被实现为一个空对象指针(即所有位都为0)。在 typeof 操作符的实现中,空对象的类型被标记为 "object",因此 typeof null 也返回 "object"。 语言规范: 这个行为是 ECM
判断数组的方式有哪些?
Posted on:2024年8月22日 at 04:06判断一个值是否为数组的方式有多种: 1. Array.isArray() 方法 描述:这是 ES5 引入的标准方法,推荐用于检查一个值是否为数组。 语法:Array.isArray(value) 示例:console.log(Array.isArray([1, 2, 3])); // true console.log(Array.isArray('hello')); // false 2. ins
说说对 XMLHttpRequest 对象的了解
Posted on:2024年8月21日 at 01:09XMLHttpRequest 对象用于在浏览器中发起异步 HTTP 请求,以便与服务器进行数据交换,而无需重新加载整个页面。 主要功能: 发起请求:支持 GET、POST、PUT、DELETE 等 HTTP 方法。 异步处理:可以以异步方式发送请求,避免阻塞用户界面。 处理响应:能够接收服务器返回的数据,并根据需要处理,比如更新页面内容。 事件处理:支持 onreadystatechange 事件
哪些原因会导致js里this指向混乱?
Posted on:2024年8月20日 at 11:19以下是一些常见的导致 this 指向混乱的原因: 1. 普通函数调用 在普通函数调用中,this 的值取决于调用该函数的上下文。如果函数不是作为对象的方法调用,this 通常指向全局对象(在浏览器中是 window,在 Node.js 中是 global)。例如: function foo() { console.log(this); } foo(); // 在浏览器中输出 window 2. 事
get 请求的参数是否能够使用数组?
Posted on:2024年8月20日 at 11:14GET 请求的参数可以使用数组。 虽然在 URL 查询字符串中直接表示数组略有复杂,但有几种常见的方式来实现数组的传递。以下是一些常见的处理数组参数的方法: 1. 使用重复的参数名 最简单的方法是使用重复的参数名,每个数组元素作为一个独立的参数传递。例如,传递一个数组 [1, 2, 3] 可以表示为: ?numbers=1&numbers=2&numbers=3 这种方式常见于许多后端框架和库,它
es5 中的类和es6中的class有什么区别?
Posted on:2024年8月18日 at 12:57在es5中主要是通过构造函数方式和原型方式来定义一个类,在es6中我们可以通过class来定义类。 一、class类必须new调用,不能直接执行。 class类执行的话会报错,而es5中的类和普通函数并没有本质区别,执行肯定是ok的。 二、class类不存在变量提升 图2报错,说明class方式没有把类的定义提升到顶部。 三、class类无法遍历它实例原型链上的属性和方法 function Foo
Object.prototype.hasOwnProperty() 作用是什么?
Posted on:2024年8月16日 at 12:07Object.prototype.hasOwnProperty() 是一个用于检查对象是否具有某个指定的自有属性的方法。这个方法的作用是确认对象自身是否包含某个属性,而不是通过原型链继承的属性。 作用 检查自有属性:hasOwnProperty 只检查对象自身是否具有指定的属性,不会检查原型链上的属性。 防止属性冲突:在遍历对象属性时(如使用 for...in 循环),可以使用 hasOwnPro
一直在 window 上面挂内容(数据,方法等等),是否有什么风险?
Posted on:2024年8月16日 at 12:04将内容一直挂在 window 对象上可能带来以下风险和问题: 1. 全局命名冲突 window 对象是全局对象,将内容挂载到 window 上可能会导致命名冲突。不同的脚本或库可能会使用相同的全局变量名,导致冲突和意外的行为。 2. 性能问题 频繁地在 window 对象上添加和修改属性可能会影响性能,特别是当这些操作涉及大量数据时。window 对象的复杂度增加可能会导致浏览器的内存使用和处理速
Javascript 数组中有哪些方法可以改变自身,哪些不可以?
Posted on:2024年8月15日 at 23:14在 JavaScript 中,数组方法可以分为改变原数组的方法和不改变原数组的方法。下面是对这些方法的详细分类: 改变自身的方法 这些方法会直接修改数组本身: push(): 向数组末尾添加一个或多个元素。 let arr = [1, 2, 3]; arr.push(4); // arr 是 [1, 2, 3, 4] pop(): 从数组末尾删除一个元素,并返回该元素。 let arr = [1,
说说对 new Function 的理解
Posted on:2024年8月15日 at 23:12new Function 是 JavaScript 中创建函数的一种方式,它允许动态地生成和执行函数。与 eval 不同,new Function 主要用于创建函数,而不是执行任意的 JavaScript 代码。它接受一个或多个参数,最后一个参数是函数体,其余参数是函数的参数列表。 基本语法 new Function ([arg1, arg2, ..., argN], functionBody)
说说你对 eval 的理解
Posted on:2024年8月15日 at 23:10eval 是 JavaScript 的一个内置函数,用于将字符串作为 JavaScript 代码进行执行。它接受一个字符串作为参数,并在当前的作用域中执行这段代码。 基本用法 eval("console.log('Hello, world!');"); // 输出: Hello, world! 特性和影响 动态代码执行: eval 允许在运行时动态地执行代码。这对于一些需要动态生成和执行代码的场景
JavaScript 中的变量在内存中的具体存储形式是什么
Posted on:2024年8月15日 at 23:05在 JavaScript 中,变量在内存中的具体存储形式取决于变量的类型。JavaScript 变量主要有两种类型:基本数据类型和引用数据类型。它们的存储和管理方式有所不同。 1. 基本数据类型 基本数据类型包括:undefined、null、boolean、number、string 、symbol和bigint。这些类型的变量直接存储值: 存储形式: 值存储:基本数据类型的变量在内存中直接存储
JavaScript 对象的底层数据结构是什么?
Posted on:2024年8月15日 at 23:02JavaScript 对象的底层数据结构主要基于 哈希表(Hash Table)。哈希表是一种使用哈希函数将键映射到特定的存储位置的数据结构。JavaScript 对象的键值对存储机制的底层实现与哈希表有相似之处。以下是对 JavaScript 对象底层数据结构的详细解释: 1. 哈希表 概念: 哈希表是一种数据结构,它通过哈希函数将键(通常是字符串或数字)映射到一个数组的索引位置。在 JavaS
数组里面有10万个数据,取第一个元素和第10万个元素的时间相差多少?
Posted on:2024年8月15日 at 13:58在 JavaScript 中,访问数组的任意元素(如第一个或第十万个元素)是常数时间操作,即 O(1) 时间复杂度。这意味着不论数组的大小如何,访问数组的某个元素的时间复杂度都是固定的。 具体来说: 访问第一个元素:array[0] 访问第十万个元素:array[99999] 这两种访问方式的时间复杂度都是 O(1)。 在实际操作中,现代浏览器和 JavaScript 引擎对数组的随机访问优化得非
为什么普通 for 循环的性能高于 forEach ?
Posted on:2024年8月15日 at 13:55普通 for 循环通常在性能上优于 forEach 的原因有以下几点: 1. 函数调用开销 forEach:在每次迭代时,forEach 需要调用回调函数。这意味着每次迭代都会发生额外的函数调用开销,包括创建函数上下文、传递参数等。 for:普通的 for 循环直接在循环体内执行代码,没有函数调用开销。 2. 函数创建和管理 forEach:forEach 需要创建一个回调函数并管理它。对于大量数
对象取值中 a.b.c.d 和 a['b']['c']['d'] 有何区别?
Posted on:2024年8月15日 at 00:01使用区别 在 JavaScript 中,对象的取值可以使用两种方式,即使用点号(.)和使用方括号([])。对于对象的多层嵌套属性,可以使用两种方式分别取值,例如: cssCopy codevar obj = {a: {b: {c: {d: 123}}}}; var d1 = obj.a.b.c.d; var d2 = obj['a']['b']['c']['d']; 这两种方式获取的结果是相同的,
箭头函数为何不能作为构造函数使用?
Posted on:2024年8月14日 at 23:58在箭头函数中,this指向的是定义时所在的对象,而不是使用时所在的对象。换句话说,箭头函数没有自己的this,而是继承父作用域中的this。 看个例子: var person = { name:'张三', age:18, getName:function(){ console.log('我的名字是:'+this.name) }, getAge:()=>{ console.log('我的年龄是:'+
[3, 15, 8, 29, 102, 22].sort(),结果是多少,为什么?
Posted on:2024年8月14日 at 23:50对于数组 [3, 15, 8, 29, 102, 22] 使用 .sort() 方法,结果是 [102, 15, 22, 29, 3, 8]。 原因: Array.prototype.sort() 方法默认是按字典顺序(即字符串的顺序)对数组元素进行排序的。它会将数组中的元素转换为字符串,然后按字典顺序比较这些字符串。 在这个例子中,排序过程如下: 转换为字符串: 3 -> "3" 15 -> "
全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?
Posted on:2024年8月14日 at 23:47在 JavaScript 中,const 和 let 声明的变量不直接添加到全局 window 对象上,这与 var 声明的变量不同。下面是对 const 和 let 的详细解释,以及如何访问这些变量的说明: const 和 let 的声明和作用域 作用域: const 和 let 的作用域是块级作用域(block scope),意味着它们的作用范围是被它们声明的代码块(例如函数、循环或条件语句)
js 中对于超过 Number 最大值的数怎么处理?
Posted on:2024年8月14日 at 23:39在 JavaScript 中,Number 类型的最大值为 Number.MAX_VALUE。当计算结果超过这个最大值时,会出现以下情况: 1. 使用 Infinity 描述:当计算结果超出 Number.MAX_VALUE,JavaScript 会返回 Infinity。 示例:const largeNumber = Number.MAX_VALUE * 2; // 结果是 Infinity c
WebWorker、SharedWorker 和 ServiceWorker 有哪些区别?
Posted on:2024年8月14日 at 23:23WebWorker、SharedWorker 和 ServiceWorker 都是 Web API 提供的用于在后台线程执行 JavaScript 代码的机制,但它们有不同的用途和特性。下面是它们的主要区别: 1. WebWorker 作用:用于在后台线程中执行 JavaScript 代码,避免阻塞主线程(UI线程)。 生命周期:与页面的生命周期关联,当页面关闭时,WebWorker 也会终止。
说说 axios 的拦截器原理及应用,并简单手写核心逻辑
Posted on:2024年8月14日 at 20:20Axios 的拦截器(interceptors)允许你在请求或响应被处理之前,进行一些自定义的处理或修改。拦截器提供了一个强大的机制来对请求和响应进行全局处理,比如添加认证信息、处理错误、或修改请求数据等。 1. 拦截器原理 请求拦截器:在请求发送到服务器之前,可以对请求进行修改、添加头信息、处理请求数据等。 响应拦截器:在接收到响应数据之前,可以对响应数据进行修改或处理错误。 2. 拦截器应用
JS 内存泄露的问题该如何排查?
Posted on:2024年8月14日 at 19:441. 了解常见的内存泄露类型 全局变量:未声明的变量被添加到全局作用域。 闭包:长时间持有对外部作用域的引用。 事件监听器:未正确移除的事件监听器。 定时器:未清除的 setInterval 或 setTimeout。 DOM 引用:移除 DOM 元素后仍有对其的引用。 2. 使用开发者工具进行排查 Chrome DevTools 提供了内存分析工具,可以帮助检测和修复内存泄露问题。 步骤: 检查
解释一下原型、构造函数、实例、原型链 之间的关系?
Posted on:2024年8月14日 at 14:08在 JavaScript 中,原型、构造函数、实例和原型链是构建和继承对象的核心概念。它们之间的关系如下: 1. 原型(Prototype) 定义:每个 JavaScript 对象都有一个原型(__proto__),这个原型也是一个对象。原型对象可以包含共享的属性和方法,这些属性和方法可以被所有实例访问。 作用:原型用于实现对象的继承。在 JavaScript 中,所有对象都可以从其原型中继承属性
js 对象可以使用 for...of 迭代吗?
Posted on:2024年8月14日 at 12:25JavaScript 对象本身并不能直接使用 for...of 迭代,因为它并不是一个可迭代对象(iterable)。 但是,如果我们想要遍历对象的属性,可以使用 for...in 循环,例如: const obj = { name: 'John', age: 30, city: 'New York' }; for (let prop in obj) { console.log(prop + ':
postMessage 是如何解决跨域问题的?
Posted on:2024年8月14日 at 12:15postMessage 是一种在不同源(域)之间进行安全通信的机制,可以解决跨域问题。以下是 postMessage 解决跨域问题的原理及其使用方式: 1. 原理 postMessage 方法 允许跨源通信,即使这些源在不同的域名、协议或端口下。这是通过以下方式实现的: 安全性:postMessage 允许页面向另一个窗口(如 iframe、弹出窗口或另一个 tab)发送消息,而不管它们是否同源。
如何检测对象是否循环引用?
Posted on:2024年8月14日 at 12:08例如下面的场景, 已经出现循环引用了, 如何检测? const foo = { foo: "Foo", bar: { bar: "Bar", }, }; foo.bar.baz = foo; // 循环引用! 检测对象是否循环引用通常是为了防止无限递归,特别是在处理 JSON 序列化、深拷贝或图遍历时。以下是几种常见的检测对象是否循环引用的方法: 1. 使用 Set 进行检测 一种常见的方法是使用
怎么理解ES6中 Generator的?使用场景有哪些?
Posted on:2024年8月14日 at 12:05一、介绍 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同 回顾下上文提到的解决异步的手段: 回调函数 promise 那么,上文我们提到promsie已经是一种比较流行的解决异步方案,那么为什么还出现Generator?甚至async/await呢? 该问题我们留在后面再进行分析,下面先认识下Generator Generator函数 执行 Genera
async/await 原理, 手写 async 函数?
Posted on:2024年8月14日 at 12:03async/await 的本质 async/await 是 ECMAScript 2017(ES8)中引入的一个语言特性,用于处理异步编程。async/await 实际上是对 Promise 的封装,通过让开发者以同步的方式编写异步代码,使得代码更加易读和易于维护。 async/await 是一种更加高级的异步编程方式,它使用了 Promise 作为底层实现,可以更好地处理异步编程中的错误和异常,
说说你对 Promise 的了解?
Posted on:2024年8月14日 at 12:01Promise 对象 1、Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案 —— 回调函数和事件 —— 更合理和更强大。它由社区最早提出和实现, ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 Promise对象有以下两个特点。 ( 1 )对象的状态不受外界影响。 Promise对象代表一个异步操作,有三种状态:Pending(进行中)、R
bind、call、apply 有什么区别?如何实现一个bind?
Posted on:2024年8月10日 at 21:45一、作用 call 、apply 、bind 作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this指向 那么什么情况下需要改变this的指向呢?下面举个例子 var name="lucy"; var obj={ name:"martin", say:function () { console.log(this.name); } }; obj.say(); //martin,this指
如何判断一个元素是否在可视区域中?
Posted on:2024年8月10日 at 21:42一、用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值(例如 100 px),从而实现一些常用的功能,例如: 图片的懒加载 列表的无限滚动 计算广告元素的曝光情况 可点击链接的预加载 二、实现方式 判断一个元素是否在可视区域,我们常用的有三种办法: offsetTop、scrollTop getBoundingC
大文件怎么实现断点续传?
Posted on:2024年8月10日 at 21:41一、是什么 不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂 文件上传简单,文件变大就复杂 上传大文件时,以下几个变量会影响我们的用户体验 服务器处理数据的能力 请求超时 网络波动 上传时间会变长,高频次文件上传失败,失败后又需要重新上传等等 为了解决上述问题,我们需要对大文件上传单独处理 这里涉及到分片上传及断点续传两个概念 分片上传 分片上传,就是将所要上传的文件,按照一定的大小,将
如何实现上拉加载,下拉刷新?
Posted on:2024年8月10日 at 21:40一、前言 下拉刷新和上拉加载这两种交互方式通常出现在移动端中 本质上等同于PC网页中的分页,只是交互形式不同 开源社区也有很多优秀的解决方案,如iscroll、better-scroll、pulltorefresh.js库等等 这些第三方库使用起来非常便捷 我们通过原生的方式实现一次上拉加载,下拉刷新,有助于对第三方库有更好的理解与使用 二、实现原理 上拉加载及下拉刷新都依赖于用户交互 最重要的是
微前端中的应用隔离是什么,一般是怎么实现的?
Posted on:2024年8月10日 at 21:33应用隔离问题主要分为主应用和微应用,微应用和微应用之间的JavaScript执行环境隔离,CSS样式隔离。 CSS隔离 当主应用和微应用同屏渲染时,就可能会有一些样式会相互污染,如果要彻底隔离CSS污染,可以采用CSS Module 或者命名空间的方式,给每个微应用模块以特定前缀,即可保证不会互相干扰,可以采用webpack的postcss插件,在打包时添加特定的前缀。 而对于微应用与微应用之间的
async/await 和 Promise 有什么关系?
Posted on:2024年8月10日 at 21:18Promise Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象 async/await es2017的新语法,async/await就是generator
Object.create 和 new 有什么区别?
Posted on:2024年8月10日 at 21:16js中创建对象的方式一般有两种Object.create和new const Base = function(){}; const o1 = Object.create(Base); const o2 = new Base(); 在讲述两者区别之前,我们需要知道: 构造函数Foo的原型属性Foo.prototype指向了原型对象。 原型对象保存着实例共享的方法,有一个指针constructor指回
如何中断Promise?
Posted on:2024年8月10日 at 21:15Promise 有个缺点就是一旦创建就无法取消,所以本质上 Promise 是无法被终止的,但我们在开发过程中可能会遇到下面两个需求: 中断调用链 就是在某个 then/catch 执行之后,不想让后续的链式调用继续执行了。 somePromise .then(() => {}) .then(() => { // 终止 Promise 链,让下面的 then、catch 和 finally 都不执
谈谈对 this 对象的理解
Posted on:2024年8月10日 at 19:49一、定义 函数的 this 关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别 在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定) this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象 举个例子: function baz() { // 当前调用栈是:baz // 因此,当前调用位置是全局作用域
Javascript如何实现继承?
Posted on:2024年8月10日 at 19:49一、是什么 继承(inheritance)是面向对象软件技术当中的一个概念。 如果一个类别B“继承自”另一个类别A,就把这个B称为“A的子类”,而把A称为“B的父类别”也可以称“A是B的超类” 继承的优点 继承可以使得子类具有父类别的各种属性和方法,而不需要再次编写相同的代码 在子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能
深拷贝浅拷贝有什么区别?怎么实现深拷贝?
Posted on:2024年8月10日 at 19:49一、数据类型存储 前面文章我们讲到,JavaScript中存在两大数据类型: 基本类型 引用类型 基本类型数据保存在在栈内存中 引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中 二、浅拷贝 浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝 如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址 即浅拷贝是拷贝一
谈谈 Javascript 中的类型转换机制
Posted on:2024年8月10日 at 19:49一、概述 JS 中有六种简单数据类型:undefined、null、boolean、string、number、symbol(BigInt处理stage-4阶段,不考虑),以及引用类型:object 但是我们在声明的时候只有一种数据类型,只有到运行期间才会确定当前类型 let x = y ? 1 : a; 上面代码中,x的值在编译阶段是无法获取的,只有等到程序运行时才能知道 虽然变量的数据类型是不
不会冒泡的事件有哪些?
Posted on:2024年8月10日 at 17:07在 JavaScript 和浏览器中,绝大多数事件都会按照 DOM 事件流模型冒泡,即事件会从目标元素开始向上冒泡到它的父元素,并最终到达 document 元素。然而,也有一些事件是不会冒泡的。这些事件通常直接在目标元素上触发,并不会向上传播。 以下是一些不会冒泡的事件的示例: focus:当元素获得焦点时触发,例如通过键盘或鼠标点击。这是一个不会冒泡的事件。 blur:当元素失去焦点时触发。这
如何让 var [a, b] = {a: 1, b: 2} 解构赋值成功?
Posted on:2024年8月10日 at 17:07迭代协议 题目问怎么能让var [a,b] = {a:1,b:2} 成立,那么我们首先要运行一下,看看它是怎么个不成立法。 const obj = { a:'1', b:'2', } const [a,b] = obj 运行之后打开控制台可以发现报错信息,它告诉我们obj这个对象是不可迭代的,那么我们想办法把obj变成可迭代的是不是就能解决这个问题,这要怎么做呢?想要搞明白这点我们需要先了解一下可
try...catch 可以捕获到异步代码中的错误吗?
Posted on:2024年8月10日 at 17:07不能。 以下面代码为例: try { setTimeout(() => { throw new Error('err') }, 200); } catch (err) { console.log(err); } setTimeout是一个异步函数,它的回调函数会在指定的延时后被放入事件队列,等待当前执行栈清空后才执行。因此,当setTimeout的回调函数执行并抛出错误时,try...catch已
setTimeout 延时写成0,一般可以什么场景下使用?
Posted on:2024年8月10日 at 17:07将setTimeout的延时参数设置为0通常用于创建一个宏任务,使用0延时仍然会导致一些延迟,但它比较接近于立即执行。 以下是一些通常会使用0延时的情况: UI渲染后的回调:当我们需要在当前事件循环结束后,等待浏览器完成UI渲染后再执行回调函数时,可以使用0延时。这样可以确保回调在界面更新之后执行,以避免阻塞UI线程。 异步操作处理:有时我们需要将某些操作推迟到下一个事件循环周期,以便让其他异步操
虚拟dom渲染到页面的时候,框架会做哪些处理?
Posted on:2024年8月10日 at 17:07当虚拟DOM渲染到页面时,框架通常会执行以下动作: Diff算法:框架会将新的虚拟DOM与旧的虚拟DOM进行对比,找出它们之间的差异。这个过程被称为Diff算法。Diff算法的目标是通过最小化操作次数来更新真实DOM,以提高性能。 创建和更新DOM节点:根据Diff算法的结果,框架会创建或更新需要改变的DOM节点。如果一个节点在新的虚拟DOM中存在但在旧的虚拟DOM中不存在,框架会创建该节点并添加
需要在本地实现一个聊天室,多个tab页相互通信,不能用websocket,你会怎么做?
Posted on:2024年8月10日 at 17:07可以考虑使用以下方法: 使用LocalStorage:这个存储API可在浏览器的不同标签页之间共享数据。当一个标签页发送消息时,将消息存储在LocalStorage中。其他标签页可以监听该存储区的变化,并读取最新的消息内容来实现通信效果。 // 监听变化 window.addEventListener("storage", (e) => { // todo ... }); 使用Broadcast
Proxy 能够监听到对象中的对象的引用吗?
Posted on:2024年8月10日 at 17:07Proxy可以监听到对象中的对象的引用。 当使用Proxy包装一个对象时,可以为该对象的任何属性创建一个拦截器,包括属性值为对象的情况。 下面展示了如何使用Proxy来监听对象中对象引用的变化: const obj = { nestedObj: { foo: 'bar' } } const handler = { get(target, prop, receiver) { const value
下面代码的输出是什么?
Posted on:2024年8月10日 at 17:07const obj = { fn1: () => console.log(this), fn2: function() {console.log(this)} } obj.fn1(); obj.fn2(); const x = new obj.fn1(); const y = new obj.fn2(); 在上面的代码中,obj 对象包含两个方法 fn1 和 fn2。fn1 使用箭头函数定义,而
浏览器有哪几种缓存,各种缓存的优先级是什么样的?
Posted on:2024年8月10日 at 17:07在浏览器中,有以下几种常见的缓存: 强制缓存:通过设置 Cache-Control 和 Expires 等响应头实现,可以让浏览器直接从本地缓存中读取资源而不发起请求。 协商缓存:通过设置 Last-Modified 和 ETag 等响应头实现,可以让浏览器发送条件请求,询问服务器是否有更新的资源。如果服务器返回 304 Not Modified 响应,则表示客户端本地缓存仍然有效,可直接使用缓存
Promise then 第二个参数和catch的区别是什么?
Posted on:2024年8月10日 at 17:07Promise 的 then 方法和 catch 方法都是用于处理 Promise 的 rejected 状态的情况。它们的区别在于: then 方法的第二个参数 如果 Promise 的状态变为 rejected,then 方法的第二个参数会被调用。该参数是一个函数,可以接收一个参数,即 Promise 返回的错误信息。 例如: function asyncFunction() { return
Web Worker 是什么?
Posted on:2024年8月10日 at 17:07Web Worker 是 HTML5 标准中提供的一项技术,它可以让 JavaScript 脚本在后台线程运行,从而避免阻塞 UI 线程。Web Worker 可以创建一个独立的线程来执行脚本,从而使得主线程可以专注于用户交互和响应。 Web Worker 的主要特点包括: 独立线程:Web Worker 可以在独立的线程中运行 JavaScript 代码,从而避免了在主线程中运行耗时任务的风险。
下面代码的输出是什么?
Posted on:2024年8月10日 at 17:07var name = '123'; var obj = { name: '456', print: function() { function a() { console.log(this.name); } a(); } } obj.print(); 上述代码输出结果为 "123"。解释如下: 在全局作用域中声明了变量 name,值为字符串 "123"。 声明一个对象 obj,包含属性 name
如果要设计一个转盘组件,你会考虑哪些方面?有哪些是需要和业务方确认的技术细节?另外,如何从前端的角度进行防刷?
Posted on:2024年8月10日 at 17:07设计一个转盘组件需要考虑以下几个方面: 功能需求:明确组件的功能需求,例如抽奖逻辑、转盘样式和动画效果等。 技术选型:选择合适的技术实现该组件,例如 CSS3 动画或 Canvas 绘图等。 数据处理:处理与后端交互的数据流程和数据结构,例如抽奖机会计数、奖品种类和数量等。 用户体验:优化用户体验,例如加载速度、响应时间、错误提示和动画效果等。 安全性:确保组件的安全性,例如防止刷奖、重复领奖和作
怎么实现虚拟列表?
Posted on:2024年8月10日 at 17:07虚拟列表是一种优化长列表渲染性能的技术,它只渲染可见区域内的部分内容,从而大幅降低了页面渲染的复杂度。 具体而言,实现虚拟列表需要以下步骤: 计算可见区域:首先需要计算出当前可见区域内的列表项数量和位置。 渲染可见区域:只渲染当前可见区域内的列表项,而不是整个列表。 动态调整列表高度:由于只渲染了部分列表项,因此需要动态调整列表容器的高度,以确保滚动条可以正确地显示并且用户可以滚动整个列表。 延迟
async/await、generator、promise 这三者的关联和区别是什么?
Posted on:2024年8月10日 at 17:07promise与async/await 函数都是用来解决JavaScript中的异步问题,从最开始的回调函数处理异步,到Promise处理异步,到Generator处理异步,再到Async/await处理异步,每一次的技术更新都使得JavaScript处理异步的方式更加优雅。 从目前来看,Async/await被认为是异步处理的终极解决方案,让JS的异步处理越来越像同步任务。 关联 async/a
mouseEnter 和 mouseOver 有什么区别?
Posted on:2024年8月10日 at 17:07mouseenter 和 mouseover 是两个用于处理鼠标进入元素时的事件,但它们在一些关键点上有所不同: 事件冒泡: mouseenter:这个事件在鼠标指针首次进入特定元素(或其子元素)时触发。当鼠标进入元素时,会触发该元素的 mouseenter 事件,但不会在元素的子元素上冒泡。因此,该事件通常用于检测鼠标首次进入元素时的动作。 mouseover:这个事件在鼠标指针移动到某个元素
说说你对 ToPrimitive 的理解
Posted on:2024年8月10日 at 17:07ToPrimitive 是一个抽象操作,用于将一个值转换为原始值(primitive value),即字符串、数字或布尔值。 在 JavaScript 中,当需要将一个非原始值用作原始值时,会自动调用 ToPrimitive 操作。例如,在使用加法运算符时,如果其中一个操作数不是原始值,则会将其转换为原始值,这就是通过调用 ToPrimitive 来实现的。 ToPrimitive 操作的实现方式
说说对 requestIdleCallback 的理解
Posted on:2024年8月10日 at 17:07requestIdleCallback 是一个浏览器 API,它允许我们在浏览器空闲时执行一些任务,以提高网页的性能和响应速度。 通常情况下,JavaScript 代码会占用主线程,从而阻塞了其他的任务。当页面需要进行一些复杂计算、渲染大量的DOM元素等操作时,就会导致用户的交互体验变得缓慢和卡顿。 requestIdleCallback 的作用就是将一些非关键性的任务从主线程中分离出来,等到浏览
页面加载的过程中,JS 文件是不是一定会阻塞 DOM 和 CSSOM 的构建?
Posted on:2024年8月10日 at 17:07答案:不一定 JavaScript阻塞DOM和CSSOM的构建的情况主要集中在以下两个方面: JavaScript文件被放置在head标签内部 当JavaScript文件被放置在head标签内部时,浏览器会先加载JavaScript文件并执行它,然后才会继续解析HTML文档。因此,如果JavaScript文件过大或服务器响应时间过长,就会导致页面一直处于等待状态,进而影响DOM和CSSOM的构建。
说说你对轮询的理解
Posted on:2024年8月10日 at 17:07什么是轮询? 轮询是指在一定的时间间隔内,定时向服务器发送请求,获取最新数据的过程。轮询通常用于从服务器获取实时更新的数据。 轮询和长轮询有什么区别? 轮询是在固定的时间间隔内向服务器发送请求,即使服务器没有数据更新也会继续发送请求。而长轮询是先发送一个请求,服务器如果没有数据更新,则不会立即返回,而是将请求挂起,直到有数据更新时再返回结果。 前端轮询的实现方式有哪些? 前端轮询的实现方式有两种:
js函数有哪几种声明方式?有什么区别?
Posted on:2024年8月10日 at 17:07有 表达式 和 声明式 两种函数声明方式 函数的声明式写法为:function test(){},这种写法会导致函数提升,所有通过function关键字声明的变量都会被解释器优先编译,不管声明在什么位置都可以调用它,但是它本身并不会被执行。 test(); // 测试 function test() { console.log("测试"); } test(); // 测试 函数的表达式写法为:va
说说你对“立即执行函数”的理解
Posted on:2024年8月10日 at 17:07什么是立即执行函数? JS立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行。 立即执行函数的两种常见写法: 匿名函数包裹在一个括号运算符中,后面跟一个小括号 (function(){ //... })() 匿名函数后面跟一个小括号,整个包裹在一个括号运算符中 (function(){ //... }()) (),!,+
如何把一个对象变成可迭代对象?
Posted on:2024年8月10日 at 17:07可迭代对象(Iterable object)是数组的泛化,这个概念是在说任何对象都可以被定制为可在 for..of 循环中使用的对象。 也就是说,可以应用 for..of 的对象被称为 可迭代对象。 迭代器 在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何
版本号排序
Posted on:2024年8月10日 at 17:07有一组版本号如下['0.1.1', '2.3.3', '0.302.1', '4.2', '4.3.5', '4.3.4.5']。 现在需要对其进行排序,排序的结果为 ['4.3.5','4.3.4.5','2.3.3','0.302.1','0.1.1'] 本题目的实现有很多不同的思路,在这里先给大家介绍一种非常简洁,也非常有意思的实现方案: const arr=['0.1.1', '2.3.3
说说你对 Iterator, Generator 和 Async/Await 的理解
Posted on:2024年8月10日 at 17:07这里重点理解他们三者分别是什么,有什么区别,以及分别适用什么场景 Iterator Iterator是最简单最好理解的。 简单的说,我们常用的 for of 循环,都是通过调用被循环对象的一个特殊函数 Iterator 来实现的,但是以前这个函数是隐藏的我们无法访问, 从 Symbol 引入之后,我们就可以通过 Symbol.iterator 来直接读写这个特殊函数。 对于循环语句来说,他并不关心
Map 和 WeakMap 有什么区别?
Posted on:2024年8月10日 at 17:07Map 1.传统对象结构 Map本质上是一个键值对的集合。和传统对象结构相比,传统对象只能用字符串作为键名,这在使用上造成了很大的限制。 const data = {} //element为节点对象 const element = document.querySelector('.node') console.log(element) //输出div.node对象 console.log(elem
如何判断某个字符串长度(要求支持表情)?
Posted on:2024年8月10日 at 17:07大家看到题目,可能首先想到的是 str.length 获取字符串的长度。 其实 JS 中的字符串长度是个奇怪的设定,很多编程语言,获取字符串的长度是得到字节长度,比如一个正常的汉字是两个字节,但在 js 中,'汉'.length 是 1 。看上去很方便,殊不知,这个特性埋下的坑。 比如: 😀 : '😀'.length 得到的是 2 𠮷 : '𠮷''.length 得到的也是 2 ES6 里
说说你对模块化方案的理解,比如 CommonJS、AMD、CMD、ES Module 分别是什么?
Posted on:2024年8月10日 at 17:07时间轴:CommonJS --> AMD --> CMD --> ES Module CommonJS 常用于:服务器端,node,webpack 特点:同步/运行时加载,磁盘读取速度快 语法: // 1. 导出:通过module.exports或exports来暴露模块 module.exports = { attr1, attr2 } exports.attr = xx 注意不可以expor
如果使用 Math.random() 计算中奖概率会有什么问题吗?
Posted on:2024年8月10日 at 17:07一、引言 我们日常开发经常会用到随机数,基本上我接触下来,都是使用 Math.random() 生成的。 例如生成随机ID: document.body.id = ('_' + Math.random()).replace('0.', ''); `` 请问这样实现有没有问题? 回答:没有问题。 例如随机排序: ```js [1, 2, 3, 4, 5].sort(_ => Math.random(
相比于npm和yarn,pnpm的优势是什么?
Posted on:2024年8月10日 at 17:07pnpm对比npm/yarn的优点: 更快速的依赖下载 更高效的利用磁盘空间 更优秀的依赖管理 我们按照包管理工具的发展历史,从 npm2 开始讲起: npm2 用 node 版本管理工具把 node 版本降到 4,那 npm 版本就是 2.x 了。 然后找个目录,执行下 npm init -y,快速创建个 package.json。 然后执行 npm install express,那么 exp
如何判断页面是通过PC端还是移动端访问?
Posted on:2024年8月10日 at 17:07一、navigator.userAgent 最简单的方法就是分析浏览器的 user agent 字符串,它包含了设备信息。 JS 通过navigator.userAgent属性拿到这个字符串,只要里面包含mobi、android、iphone等关键字,就可以认定是移动设备。 if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) { // 当前设
说说你对 pnpm 的了解
Posted on:2024年8月10日 at 17:07pnpm 的官方文档是这样说的: Fast, disk space efficient package manager pnpm 本质上就是一个包管理器,这一点跟 npm/yarn 没有区别,但它作为杀手锏的两个优势在于: 包安装速度极快; 磁盘空间利用非常高效。 pnpm 与 npm/yarn 相似,也是一个包管理器,但与他们不同的是,作者设计了一套理论上更完善的依赖结构以及高效的文件复用,来
map和 filter 有什么区别?
Posted on:2024年8月10日 at 17:07参数 首先,map和filter函数的参数,是完全相同的 array.map(function(currentValue,index,arr), thisValue) array.filter(function(currentValue,index,arr), thisValue) currentValue:数组元素; index:索引 arr:原数组; thisValue:作为该执行回调时使用,
导致页面加载白屏时间长的原因有哪些,怎么进行优化?
Posted on:2024年8月10日 at 17:07一、白屏时间 白屏时间:即用户点击一个链接或打开浏览器输入URL地址后,从屏幕空白到显示第一个画面的时间。 二、白屏时间的重要性 当用户点开一个链接或者是直接在浏览器中输入URL开始进行访问时,就开始等待页面的展示。页面渲染的时间越短,用户等待的时间就越短,用户感知到页面的速度就越快。这样可以极大的提升用户的体验,减少用户的跳出,提升页面的留存率。 三、白屏的过程 从输入url,到页面的画面展示的
JQuery中的$(document).ready与window.onload有什么区别?
Posted on:2024年8月10日 at 17:06定义 再说两者之前先简单说明一下window与document的区别: window window对象表示浏览器中打开的窗口。 window对象可以省略,如:window.console.log()等价于console.log() document document对象是window对象的一部分,如:document.body 等价于 window.document.body 浏览器的html文档
map 和 forEach 有什么区别?
Posted on:2024年8月10日 at 17:06定义 我们首先来看一看MDN上对Map和ForEach的定义: forEach(): 针对每一个元素执行提供的函数(executes a provided function once for each array element)。 map(): 创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来(creates a new array with the results o
前端跨页面通信,你知道哪些方法?
Posted on:2024年8月10日 at 17:06在前端中,有几种方法可用于实现跨页面通信: LocalStorage 或 SessionStorage:这两个 Web 存储 API 可以在不同页面之间共享数据。一个页面可以将数据存储在本地存储中,另一个页面则可以读取该数据并进行相应处理。通过监听 storage 事件,可以实现数据的实时更新。 Cookies:使用 Cookies 也可以在不同页面之间传递数据。通过设置和读取 Cookie 值,
怎么把函数中的 arguments 转成数组?
Posted on:2024年8月10日 at 17:06函数中的 arguments 是一个对象,不是一个数组,严格来说它是一个类数组对象。 1、调用数组的原型方法来转换 var foo = function(a,b){ var arr = Array.prototype.slice.call(arguments); console.log(arr) } foo(1,2) //(2) [1, 2] 2、使用ES6的新语法 Array.from() 来转
如何顺序执行10个异步任务?
Posted on:2024年8月10日 at 17:06解法1:for 循环 + await 简单的 for 循环是依次进行循环的,不像 Array.forEach,Array.map 方法是并发执行的,利用这一特点加 async / await 很容易写出下面这样的代码: (async () => { const sleep = delay => { return new Promise((resolve, reject) => { setTimeo
如何让Promise.all在抛出异常后依然有效
Posted on:2024年8月10日 at 17:06在处理多个并发请求时,我们一般会用Promise.all()方法。 该方法指当所有在可迭代参数中的 promises 已完成,或者第一个传递的 promise(指 reject)失败时,返回 promise。 但是当其中任何一个被拒绝的话。Promise.all([..])就会立即被拒绝,并丢弃来自其他所有promis的全部结果。 也就是说,promise.all 中任何一个 promise 出现
如何获取页面的滚动距离值?
Posted on:2024年8月10日 at 17:06在获取页面滚动距离的高度时候,往往有不同的获取方式,而且不同的属性浏览器支持稍有差别: pageYOffset:属window对象,IE9+、Firefox、Chrome、Opera均支持该方式获取页面滚动敢赌值,并且会忽略DOCTYPE定义规则。 window.pageYOffset scrollY:属于window对象,Firefox、Chrome、Opera均支持,IE不支持,忽略DOCTY
用js实现二叉树的定义和基本操作
Posted on:2024年8月10日 at 17:06树是计算机科学中经常用到的一种数据结构。树是一种非线性的数据结构,以分层的方式存储数据。树被用来存储具有层级关系的数据,比如文件系统中的文件;树还被用来存储有序列表。 二叉树具有诸多优点。相对于链表来说,二叉树在进行查找时速度非常快,而相对于数组来说,为二叉树添加或删除元素也非常快。 二叉树 二叉树是一种特殊的树,表现在它的子节点个数不超过两个。且二叉树的子树有左右之分,其次序不能任意颠倒。 在实
什么是同步和异步?
Posted on:2024年8月10日 at 17:06JS 是一门单线程的编程语言,这就意味着一个时间里只能处理一件事,也就是说JS引擎一次只能在一个线程里处理一条语句。 虽然单线程简化了编程代码,因为这样咱们不必太担心并发引出的问题,这也意味着在阻塞主线程的情况下执行长时间的操作,如网络请求。 想象一下从API请求一些数据,根据具体的情况,服务器需要一些时间来处理请求,同时阻塞主线程,使网页长时间处于无响应的状态。这就是引入异步 JS 的原因。使用
非递归遍历二叉树
Posted on:2024年8月10日 at 17:06二叉树使用递归实现前中后序遍历是非常容易的,本文给出非递归实现前中后序遍历的方法,核心的思想是使用一个栈,通过迭代来模拟递归的实现过程。 下面实现中root代表二叉树根节点,每个节点都具有left,right两个指针,分别指向当前节点左右子树,一个val属性代表当前节点的值 前序遍历(preorderTraversal) const preorderTraversal = function(roo
说说你的ES6-ES12的了解
Posted on:2024年8月10日 at 17:06ES6(2015) 1. 类(class) class Man { constructor(name) { this.name = '小豪'; } console() { console.log(this.name); } } const man = new Man('小豪'); man.console(); // 小豪 2. 模块化(ES Module) // 模块 A 导出一个方法 expor
['1','2','3'].map(parseInt) 的返回值是什么?
Posted on:2024年8月10日 at 17:06首先整个题目考校的是两个函数,和一个字符串转数字的概念 数组的map函数,接受三个参数,当前值,当前索引,当前数组。 parseInt接受两个参数,需要转换的字符串,基数(基数取值范围2~36) var new_array = arr.map(function callback(currentValue, index, array) { // Return element for new_arra
怎么预防按钮的重复点击?
Posted on:2024年8月10日 at 17:06先看看在那些场景会导致重复请求: 手速快,不小心双击操作按钮。 很小心的点击了一次按钮,因为请求响应比较慢,页面没有任何提示,怀疑上次点击没生效,再次点击操作按钮。 很小心的点击了一次按钮,因为请求响应比较慢,页面没有任何提示,刷新页面,再次点击操作按钮。 前端方案 我们可以对症下药: 控制按钮,在短时间内被多次点击,第一次以后的点击无效。 控制按钮,在点击按钮触发的请求响应之前,再次点击无效。
JavaScript 中如何取消请求
Posted on:2024年8月10日 at 17:06JavaScript 实现异步请求就靠浏览器提供的两个 API —— XMLHttpRequest 和 Fetch。我们平常用的较多的是 Promise 请求库 axios,它基于 XMLHttpRequest。 本篇带来 XMLHttpRequest、Fetch 和 axios 分别是怎样“取消请求”的。 取消 XMLHttpRequest 请求 当请求已经发送了,可以使用 XMLHttpReq
怎么实现大型文件上传?
Posted on:2024年8月10日 at 17:06大文件快速上传的方案,其实无非就是将 文件变小,也就是通过 压缩文件资源 或者 文件资源分块 后再上传。 具体来说,可以考虑以下几种方法: 分片上传(Chunked Upload):将大文件拆分成小的文件块(chunk),然后通过多个并行的请求依次上传这些文件块。服务器接收到每个文件块后进行存储,最后合并所有文件块以还原原始文件。这种方法可以降低单个请求的负载,并允许在网络中断或上传失败时可以从断
说说你对JS的模块化方案的了解
Posted on:2024年8月10日 at 17:06前言 JavaScript 语言诞生至今,模块规范化之路曲曲折折。社区先后出现了各种解决方案,包括 AMD、CMD、CommonJS 等,而后 ECMA 组织在 JavaScript 语言标准层面,增加了模块功能(因为该功能是在 ES2015 版本引入的,所以在下文中将之称为 ES6 module)。今天我们就来聊聊,为什么会出现这些不同的模块规范,它们在所处的历史节点解决了哪些问题? 何谓模块化
遍历数组的方式有哪些?
Posted on:2024年8月10日 at 17:06数组遍历的方法 for 标准的for循环语句,也是最传统的循环语句 var arr = [1,2,3,4,5] for(var i=0;i<arr.length;i++){ console.log(arr[i]) } 最简单的一种遍历方式,也是使用频率最高的,性能较好,但还能优化 优化版for循环语句 var arr = [1,2,3,4,5] for(var i=0,len=arr.length
说说你对 new.target 的理解
Posted on:2024年8月10日 at 17:06new.target 属性是 JavaScript 中一个特殊的属性,它用于检测函数或构造函数是否是通过 new 运算符被调用的。这个属性在通过 new 运算符初始化的函数或构造方法中,会返回一个指向构造方法或函数的引用。如果函数不是通过 new 运算符被调用的,new.target 的值将是 undefined。 利用 new.target,我们可以编写代码来检查一个函数是否作为构造函数被 ne
arguments 这种类数组,如何遍历类数组?
Posted on:2024年8月10日 at 17:06类数组对象 所谓的类数组对象: 拥有一个 length 属性和若干索引属性的对象 举个例子: var array = ['name', 'age', 'sex']; var arrayLike = { 0: 'name', 1: 'age', 2: 'sex', length: 3 } 即便如此,为什么叫做类数组对象呢? 那让我们从读写、获取长度、遍历三个方面看看这两个对象。 读写 console
new fn与new fn()有什么区别吗?
Posted on:2024年8月10日 at 17:06用 new 创建构造函数的实例时,通常情况下 new 的构造函数后面需要带括号(譬如:new Parent())。 有些情况下new的构造函数后带括号和不带括号的情况一致,譬如: function Parent(){ this.num = 1; } console.log(new Parent());//输出Parent对象:{num:1} console.log(new Parent);//输出
Object与Map有什么区别?
Posted on:2024年8月10日 at 17:06概念 Object 在ECMAScript中,Object是一个特殊的对象。它本身是一个顶级对象,同时还是一个构造函数,可以通过它(如:new Object())来创建一个对象。我们可以认为JavaScript中所有的对象都是Object的一个实例,对象可以用字面量的方法const obj = {}即可声明。 Map Object本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键
postMessage 有哪些使用场景?
Posted on:2024年8月10日 at 17:06window.postMessage 定义 window.postMessage() 方法可以安全地实现跨源通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全 用途 可用于两个不同的Ifrom(不同源) 之间的通讯 语法 otherWindow.postMessage(message, targetOrigin, [transfer
async/await 怎么进行错误处理?
Posted on:2024年8月10日 at 17:06一般情况下 async/await 在错误处理方面,主要使用 try/catch,像这样 const fetchData = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve('fetch data is me') }, 1000) }) } (async () => { try { const
CSS动画和JS实现的动画分别有哪些优缺点?
Posted on:2024年8月10日 at 17:06CSS动画 优点 浏览器可以对动画进行优化 代码相对简单,性能调优方向固定 对于帧速表现不好的低版本浏览器,CSS3可以做到自然降级,而JS则需要撰写额外代码 缺点 运行过程控制较弱,无法附加事件绑定回调函数 代码冗长,想用CSS实现稍微复杂一点动画,最后CSS代码都会变得非常笨重 JS动画 优点 控制能力很强, 可以在动画播放过程中对动画进行控制:开始、暂停、回放、终止、取消都是可以做到的。 动
前端实现动画有哪些方式?
Posted on:2024年8月10日 at 17:06前端常用的动画实现方式有以下种: css3的transition 属性 css3的animation 属性 原生JS动画 使用canvas绘制动画 SVG动画 Jquery的animate函数 使用gif图片 1. css3的transition transition属性: 用来设置样式的属性值是如何从一种状态平滑过渡到另外一种状态 语法: transition: property duratio
e.target 和 e.currentTarget 有什么区别?
Posted on:2024年8月10日 at 17:06冒泡 & 捕获 当你触发一个元素的事件的时候,该事件从该元素的祖先元素传递下去,此过程为捕获,而到达此元素之后,又会向其祖先元素传播上去,此过程为冒泡 <div id="a"> <div id="b"> <div id="c"> <div id="d">哈哈哈哈哈</div> </div> </div> </div> addEventListener addEventListener是为元素绑定事
写一个返回数据类型的函数,要求自定义的类实例化的对象返回定义的类名
Posted on:2024年8月10日 at 17:06Javascript是一门动态类型的语言,一个变量从声明到最后使用,可能经过了很多个函数,而数据类型也会发生改变,那么,对一个变量的数据类型判断就显得尤为重要。 获取数据类型 我们先来看下怎么获取一个数据的类型。 typeof是否能正确判断类型? 由于由于历史原因,在判断原始类型时,typeof null会等于object。而且对于对象(Object)、数组(Array)来说,都会转换成objec
async、await 实现原理
Posted on:2024年8月10日 at 17:06JavaScript 异步编程回顾 由于 JavaScript 是单线程执行模型,因此必须支持异步编程才能提高运行效率。异步编程的语法目标是让异步过程写起来像同步过程。 1. 回调函数 回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。 const fs = require('fs') fs.readFile('/etc/passwd', (err,
RESTful 接口规范是什么?
Posted on:2024年8月10日 at 17:06RESTful 接口规范是一种设计 Web 服务接口的风格和规范,遵循 REST(Representational State Transfer)架构。它的设计原则包括以下几点: 资源(Resources):将系统中的所有事物视为资源,每个资源都有一个唯一的标识符(通常是 URL),用于对其进行操作。 统一接口(Uniform Interface):接口设计应该简单一致,包括以下几个方面: 使用标
ES5怎么实现继承
Posted on:2024年8月10日 at 17:06在 ES5 中,实现继承主要有以下几种方式: 原型链继承: 通过将一个对象的 __proto__ 属性指向另一个对象的 prototype 属性,可以实现继承。function Parent() { this.parentProperty = true; } Parent.prototype.getParentProperty = function() { return this.parentPr
请简述 == 的机制
Posted on:2024年8月10日 at 17:06大家知道,==是JavaScript中比较复杂的一个运算符。它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一。 在仔细阅读了ECMAScript规范的基础上,我画了一张图,我想通过它你会彻底地搞清楚关于==的一切。同时,我也试图通过此文向大家证明==并不是那么糟糕的东西,它很容易掌握,甚至看起来很合理。 先上图: 图1 ==运算规则的图形化表示 规范毕竟是给Jav
说说sourcemap的原理?
Posted on:2024年8月10日 at 17:06Source map 想必大家都不陌生。线上的代码多是压缩后的,如果线上有报错却只能调试那个代码多半是个噩梦。因此我们需要有一个桥梁帮助我们搭建起源代码及压缩后代码的联系,source map 就是起了这个作用。 以下是 MDN 对于 source map 的解释: 调试原始源代码会比浏览器下载的转换后的代码更加容易。 source map 是从已转换的代码映射到原始源的文件,使浏览器能够重构原始
AST语法树是什么?
Posted on:2024年8月10日 at 17:06AST是抽象语法树(Abstract Syntax Tree)的缩写,它是一种用于表示程序源代码结构的树状数据结构。AST可以将源代码解析为一个由节点组成的树形结构,每个节点代表着代码中的一个特定语法结构或语义概念。 在编译过程中,AST扮演了重要的角色。它被用于分析、转换和生成代码。以下是一些常见的使用情况: 解析和验证:通过解析源代码,将其转换为AST之后,可以对代码进行验证和静态分析。这包括
flexible.js实现移动端适配的原理是什么?
Posted on:2024年8月10日 at 17:06flexible.js 官方已不再维护,目前推行 vw 适配方案,本答案只是为了分析它的原理。 flexible.js存在的目的,是为了让网页在各终端上的展示效果就像缩放设计稿图片一样,在不同屏幕上等比缩放,每一个元素与整体比例保持不变,真实还原设计稿。 基本原理 设页面宽度为P(单位px) 设计稿宽度为750px 设html基准值为X(单位px) 首先将页面分为100份,份的单位为F 设1F的
JavaScript中的 sort 方法是怎么实现的?
Posted on:2024年8月10日 at 17:06本答案将介绍js中常用的几种排序算法,并结合v8中相关源码分析sort实现的策略 常见排序算法 首先温习下排序算法需要关注的两大要素 时间复杂度 描述该算法的运行时间,通常用大O描述,附上一张时间复杂度曲线图帮助理解 空间复杂度 度量一个算法在运行过程中占用存储空间大小 常见排序 常见的十大经典排序算法就不在这科普了,根据特性可将它们从不同角度进行分类 是否基于比较:比较类排序和非比较类排序 是否
前端怎么实现跨域请求?
Posted on:2024年8月10日 at 17:06什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。 同源策略限制内容有: Cookie、LocalStorage、IndexedDB 等存储性内容 DOM 节点 AJAX 请求发送后,结果被浏览器
cookie、localStorage和sessionStorage 三者之间有什么区别
Posted on:2024年8月10日 at 17:06生命周期 cookie:可设置失效时间,没有设置的话,默认是关闭浏览器后失效 localStorage:除非被手动清除,否则将会永久保存。 sessionStorage: 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除。 存放数据大小 cookie:4KB左右 localStorage和sessionStorage:可以保存5MB的信息。 http请求 cookie:每次都会携带在HTTP头
怎么实现图片懒加载?
Posted on:2024年8月10日 at 17:06懒加载是一种网页性能优化的方式,它能极大的提升用户体验。就比如说图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很经常的事了。如果每次进入页面就请求所有的图片资源,那么可能等图片加载出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视区域的图片资源。 总结出来就两个点: 全部加载的话会影响用户体验 浪费用户的流量,有些用户并不想全部看完,全部加载会耗费大量流量。
怎么解决canvas中获取跨域图片数据的问题?
Posted on:2024年8月10日 at 17:06背景 在一张图片添加相关文字,然后转化为base64数据,上传至服务器。当代码上线写完部署到测试环境,控制台报出如下错题: Uncaught (in promise) DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported 这是因为页面在请求图片
全排列
Posted on:2024年8月10日 at 17:06给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]] 示例 3: 输入:nums = [1] 输出:[[1]] 提示: 1
背包问题
Posted on:2024年8月10日 at 17:06有 N 件物品和一个容量是 V 的背包。每件物品有且只有一件。 第 i 件物品的体积是 v[i] ,价值是 w[i] 。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 示例 1: 输入: N = 3, V = 4, v = [4,2,3], w = [4,2,3] 输出: 4 解释: 只选第一件物品,可使价值最大。 示例 2: 输入: N = 3, V = 5, v
ES6有哪些新特性?
Posted on:2024年8月10日 at 17:06关于ES6和JavaScript的关系 1、ES6是对于ES2015+的俗称,也可以说是通常叫法,那么,ES6是什么呢? ES 全称是ECMAScript,它是JavaScript基础构建的一种语言,JavaScript正是建立在ECMAScript语言的基础规范中建立使用的,那么,ECMAScript的使用,对于JavaScript至关重要! 在我的理解中,ECMAScript是一种语言层面的东
jquery的链式调用是怎么实现的?
Posted on:2024年8月10日 at 17:06我们都知道 jQuery 可以链式调用,比如: $("div").eq(0).css("width", "200px").show(); 链式调用的核心就在于调用完的方法将自身实例返回。 实现一个简单的链式调用 // 定义一个对象 class listFunc { // 初始化 constructor(val) { this.arr = [...val]; return this; } // 打
js中数组是如何在内存中存储的?
Posted on:2024年8月10日 at 17:06数组不是以一组连续的区域存储在内存中,而是一种哈希映射的形式。它可以通过多种数据结构来实现,其中一种是链表。 js分为基本类型和引用类型: 基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问; 引用类型是保存在堆内存中的对象,值大小不固定,栈内存中存放的该对象的访问地址指向堆内存中的对象,JavaScript不允许直接访问堆内存中的位置,因此操作对象时,实际操
怎么实现一个扫描二维码登录PC网站的需求?
Posted on:2024年8月10日 at 17:06二维码登录本质 二维码登录本质上也是一种登录认证方式。既然是登录认证,要做的也就两件事情: 告诉系统我是谁 向系统证明我是谁 扫描二维码登录的一般步骤 扫码前,手机端应用是已登录状态,PC端显示一个二维码,等待扫描 手机端打开应用,扫描PC端的二维码,扫描后,会提示"已扫描,请在手机端点击确认" 用户在手机端点击确认,确认后PC端登录就成功了 具体流程 生成二维码 PC端向服务端发起请求,告诉服务
怎么使用 setTimeout 实现 setInterval?
Posted on:2024年8月10日 at 17:06setInterval 的作用是每隔一段指定时间执行一个函数,但是这个执行不是真的到了时间立即执行,它真正的作用是每隔一段时间将事件加入事件队列中去,只有当当前的执行栈为空的时候,才能去从事件队列中取出事件执行。所以可能会出现这样的情况,就是当前执行栈执行的时间很长,导致事件队列里边积累多个定时器加入的事件,当执行栈结束的时候,这些事件会依次执行,因此就不能到间隔一段时间执行的效果。 针对 set
异步编程有哪些实现方式?
Posted on:2024年8月10日 at 17:06JavaScript异步编程是JavaScript编程中非常关键的一部分,尤其是在处理网络请求、文件读写、定时任务等场景时。JavaScript提供了多种实现异步编程的方式,以下是其中一些主要的实现方式: 回调函数(Callbacks): 最早的异步处理方式之一,通过在函数作为参数传递给另一个函数,并在该异步操作完成时调用该回调函数。 缺点是会导致“回调地狱”(Callback Hell),即代码
怎么使用 js 实现拖拽功能?
Posted on:2024年8月10日 at 17:06在JavaScript中实现拖拽功能,通常需要监听几个关键的事件:mousedown(或touchstart对于移动设备)、mousemove(或touchmove)、mouseup(或touchend 和 touchcancel)以及mouseover(可选,用于处理元素边界外的移动)。以下是一个基本的拖拽功能的实现步骤: 1. HTML 结构 首先,你需要一个可以拖拽的元素。 <div id=
offsetWidth/offsetHeight,clientWidth/clientHeight 与 scrollWidth/scrollHeight 的区别?
Posted on:2024年8月10日 at 17:06offsetWidth、offsetHeight、clientWidth、clientHeight与scrollWidth、scrollHeight是JavaScript中用于获取元素尺寸的几个重要属性,它们各自有不同的应用场景和返回值。以下是它们之间的区别: 1. offsetWidth/offsetHeight 定义:这两个属性分别表示元素的布局宽度和高度,包括元素的边框(border)、内边
什么是“前端路由”?什么时候适合使用“前端路由”?“前端路由”有哪些优点和缺点?
Posted on:2024年8月10日 at 17:05“前端路由”是什么? 前端路由是指通过JavaScript在前端实现的一种路由机制,它允许在不重新加载整个页面的情况下,根据URL的变化来更新页面内容。这种机制主要通过监听URL的变化(如hash的变化或HTML5的History API),并在前端动态地加载和渲染相应的页面组件或内容来实现。前端路由通常用于单页面应用(SPA)中,以提供流畅的用户体验和快速的页面切换。 什么时候适合使用“前端路由
介绍一下 setTimeout 的运行机制
Posted on:2024年8月10日 at 17:05setTimeout简介 setTimeout()函数:用来指定某个函数或某段代码在多少毫秒之后执行。它返回一个整数,表示定时器timer的编号,可以用来取消该定时器。 先看个简单的例子: console.log(1); setTimeout(function () { console.log(2); }, 0); console.log(3); 问:最后的打印顺序是什么?(如果不了解js的运行机
['10', '10', '10', '10', '10'].map(parseInt)
Posted on:2024年8月10日 at 17:05parseInt parseInt() 函数解析一个字符串参数,并返回一个指定基数的整数 (数学系统的基础)。 const intValue = parseInt(string[, radix]); string 要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。 radix 一个介于2和36之间的整数(数学系统的基础),表
JavaScript中的错误有哪几种类型?
Posted on:2024年8月10日 at 17:05JavaScript中的错误类型 Error EvalError RangeError ReferenceError SyntaxError TypeError URIError Error Error是最基本的错误类型,其他的错误类型都继承自该类型。因此,所有错误的类型共享了一组相同的属性。 这个类型的错误很少见。一般使用开发人员自定义抛出的错误。 EvalError 这个错误会在使用eval(
Promise.all 和 Promise.allSettled 有什么区别?
Posted on:2024年8月10日 at 17:05一句话概括Promise.allSettled和Promise.all的最大不同:Promise.allSettled永远不会被reject。 Promise.all的痛点 当需要处理多个Promise并行时,大多数情况下Promise.all用起来是非常顺手的,比如下面这样 const delay = n => new Promise(resolve => setTimeout(resolve,
什么是“事件代理”
Posted on:2024年8月10日 at 17:05事件代理(Event Delegation)也称之为事件委托。是JavaScript中常用绑定事件的常用技巧。 顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。 事件代理的原理是DOM元素的事件冒泡。 一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。 捕获阶段:从window对象传导到目标节点(上层传到
谈谈你对事件冒泡和捕获的理解
Posted on:2024年8月10日 at 17:05事件冒泡(Event Bubbling)和事件捕获(Event Capturing)是两种在DOM(Document Object Model)中处理事件传播机制的方式。它们定义了当一个事件(如点击、鼠标移入等)发生在某个元素上时,这个事件如何传播到DOM树的其他部分。理解这两种机制对于编写高效且可维护的Web应用程序至关重要。 事件冒泡(Event Bubbling) 事件冒泡是事件传播的一种方
浏览器为什么要有跨域限制?
Posted on:2024年8月10日 at 17:05因为存在浏览器同源策略,所以才会有跨域问题。那么浏览器是出于何种原因会有跨域的限制呢。其实不难想到,跨域限制主要的目的就是为了用户的上网安全。 如果浏览器没有同源策略,会存在什么样的安全问题呢。下面从 DOM 同源策略和 XMLHttpRequest 同源策略来举例说明: 如果没有 DOM 同源策略,也就是说不同域的 iframe 之间可以相互访问,那么黑客可以这样进行攻击: 做一个假网站,里面用
document.write和innerHTML有什么区别
Posted on:2024年8月10日 at 17:05document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。 innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.inne
xml和json有什么区别?
Posted on:2024年8月10日 at 17:05JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它完全独立于语言。它基于JavaScript编程语言,易于理解和生成。 示例: {"Student":[ { "Name":"Vivek", "age":"20" }, { "Name":"Suraj", "age":"19" }, { "Name":"John", "age":"21" }, {
数据类型检测的方式有哪些?
Posted on:2024年8月10日 at 17:05(1)typeof console.log(typeof 2); // number console.log(typeof true); // boolean console.log(typeof 'str'); // string console.log(typeof []); // object console.log(typeof function(){}); // function con
ajax、axios、fetch有什么区别?
Posted on:2024年8月10日 at 17:05(1)AJAX Ajax 即“AsynchronousJavascriptAndXML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。它是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 Aja
isNaN 和 Number.isNaN 函数有什么区别?
Posted on:2024年8月10日 at 17:05NaN 全局属性 NaN 的值表示不是一个数字(Not-A-Number)。 在 JavaScript 中,NaN 最特殊的地方就是,我们不能使用相等运算符(== (en-US) 和 === (en-US))来判断一个值是否是 NaN,因为 NaN == NaN 和 NaN === NaN 都会返回 false。因此,必须要有一个判断值是否是 NaN 的方法。 方法简介 函数 isNaN 接收参数
说说你对以下几个页面生命周期事件的理解:DOMContentLoaded,load,beforeunload,unload
Posted on:2024年8月10日 at 17:05HTML 页面的生命周期包含三个重要事件: DOMContentLoaded —— 浏览器已完全加载 HTML,并构建了 DOM 树,但像 和样式表之类的外部资源可能尚未加载完成。 load —— 浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式等。 beforeunload/unload —— 当用户正在离开页面时。 每个事件都是有用的: DOMContentLoaded 事
介绍一下 tree shaking 及其工作原理
Posted on:2024年8月10日 at 17:05Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination。 tree shaking如何工作的呢? 虽然 tree shaking 的概念在 1990 就提出了,但直到 ES6 的 ES6-style 模块出现后才真正被利用起来。 在ES6以前,我们可以使用CommonJS引入模块:require(),这种引入是动态的,
浏览器和 Node 中的事件循环有什么区别?
Posted on:2024年8月10日 at 17:05浏览器 关于微任务和宏任务在浏览器的执行顺序是这样的: 执行一只task(宏任务) 执行完micro-task队列 (微任务) 如此循环往复下去 常见的 task(宏任务) 比如:setTimeout、setInterval、script(整体代码)、 I/O 操作、UI 渲染等。 常见的 micro-task 比如: new Promise().then(回调)、MutationObserver
谈谈对 window.requestAnimationFrame 的理解
Posted on:2024年8月10日 at 17:05window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。 与setTimeout相比,requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每1
浏览器一帧都会干些什么?
Posted on:2024年8月10日 at 17:05我们都知道,页面的内容都是一帧一帧绘制出来的,浏览器刷新率代表浏览器一秒绘制多少帧。原则上说 1s 内绘制的帧数也多,画面表现就也细腻。目前浏览器大多是 60Hz(60帧/s),每一帧耗时也就是在 16.6ms 左右。那么在这一帧的(16.6ms) 过程中浏览器又干了些什么呢? 通过上面这张图可以清楚的知道,浏览器一帧会经过下面这几个过程: 接受输入事件 执行事件回调 开始一帧 执行 RAF (R
谈谈 Object.defineProperty 与 Proxy 的区别
Posted on:2024年8月10日 at 17:05在 Vue2.x 的版本中,双向绑定是基于 Object.defineProperty 方式实现的。而 Vue3.x 版本中,使用了 ES6 中的 Proxy 代理的方式实现。 Object.defineProperty(obj, prop, descriptor) 使用 Object.defineProperty 会产生三个主要的问题: 不能监听数组的变化 在 Vue2.x 中解决数组监听的方法
html文档渲染过程,css文件和js文件的下载,是否会阻塞渲染?
Posted on:2024年8月10日 at 17:05浏览器内有多个进程,其中渲染进程被称为浏览器内核,负责页面渲染和执行 JS 脚本等。渲染进程负责浏览器的解析和渲染,内部有 JS 引擎线程、 GUI 渲染线程、事件循环管理线程、定时器线程、HTTP 线程。 JS 引擎线程负责执行 JS 脚本,GUI 渲染线程负责页面的解析和渲染,两者是互斥的,也就是执行 JS 的时候页面是停止解析和渲染的。这是因为如果在页面渲染的同时 JS 引擎修改了页面元素,
谈谈你对浏览器中进程和线程的理解
Posted on:2024年8月10日 at 17:05浏览器是多进程的 它主要包括以下进程: Browser 进程:浏览器的主进程,唯一,负责创建和销毁其它进程、网络资源的下载与管理、浏览器界面的展示、前进后退等。 GPU 进程:用于 3D 绘制等,最多一个。 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。 浏览器渲染进程(浏览器内核):内部是多线程的,每打开一个新网页就会创建一个进程,主要用于页面渲染,脚本执行,事件处理等。
ES6中的 Reflect 对象有什么用?
Posted on:2024年8月10日 at 17:05Reflect 对象不是构造函数,所以创建时不是用 new 来进行创建。 在 ES6 中增加这个对象的目的: 将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty),放到 Reflect 对象上。现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来的新方法将只部署在 Reflect 对象上。也就是说,从 Reflect 对象上可
说说你对 Object.defineProperty 的理解
Posted on:2024年8月10日 at 17:05Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。 该方法接受三个参数,第一个参数是 obj:要定义属性的对象,第二个参数是 prop:要定义或修改的属性的名称或 Symbol,第三个参数是 descriptor:要定义或修改的属性描述符。 const obj = {}; Object.defineProperty(ob
什么是尾调用优化和尾递归?
Posted on:2024年8月10日 at 17:05什么是尾调用? 尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。 function f(x){ return g(x); } 上面代码中,函数f的最后一步是调用函数g,这就叫尾调用。 以下两种情况,都不属于尾调用。 // 情况一 function f(x){ let y = g(x); return y; } // 情况二 function f(x){ retur
简单介绍下 ES6 中的 Iterator 迭代器
Posted on:2024年8月10日 at 17:05想必大家使用过for循环、while循环等,遍历Array获取其中的值,那其他数据结构如何通过遍历获取呢?或者这样说,是否可以提供一个统一的访问机制?来访问Object、Map、Set等。 轮到Iterator迭代器出场,Iterator迭代器就是为了解决这个问题,它提供统一的接口,为不同的数据结构提供统一的访问机制。(目前Map、Set、Array支持Iterator)。 顾名思义,Iterat
堆与栈有什么区别?
Posted on:2024年8月10日 at 17:05堆(Heap)与栈(Stack)是开发人员必须面对的两个概念,在理解这两个概念时,需要放到具体的场景下,因为不同场景下,堆与栈代表不同的含义。一般情况下,有两层含义: 程序内存布局场景下,堆与栈表示两种内存管理方式; 数据结构场景下,堆与栈表示两种常用的数据结构。 程序内存分区中的堆与栈 栈简介 栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。 其中函
forEach 中能否使用 await ?
Posted on:2024年8月10日 at 17:05function test() { let arr = [3, 2, 1]; arr.forEach(async (item) => { const res = await fetch(item); console.log(res); }); console.log("end"); } function fetch(x) { return new Promise((resolve, reject)
为什么部分请求中,参数需要使用 encodeURIComponent 进行转码?
Posted on:2024年8月10日 at 17:05一般来说,URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。 这是因为网络标准RFC 1738做了硬性规定: "...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters use
说说对 WebSocket 的了解
Posted on:2024年8月10日 at 17:05什么是WebSocket HTML5开始提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。 优点 说到优点,这里的对比参照物是HTTP协议,概括地说就是:支持双向通信,更灵活,更高效,可扩展性更好。 支持双向通信,实时性更强。 更好的二进制支持。 较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。
Promise中,resolve后面的语句是否还会执行?
Posted on:2024年8月10日 at 17:05在 JavaScript 中,当调用 Promise.resolve(value) 后,Promise 会立即变成已解决状态(fulfilled),value 会作为结果传递。但resolve 后面的语句会继续执行,因为 resolve 只是将 Promise 的状态更改为已解决,它不会中断或停止代码的执行。 以下是一个例子: new Promise((resolve, reject) => {
写一个 LRU 缓存函数
Posted on:2024年8月10日 at 17:05关于缓存,有个常见的例子是,当用户访问不同站点时,浏览器需要缓存在对应站点的一些信息,这样当下次访问同一个站点的时候,就可以使访问速度变快(因为一部分数据可以直接从缓存读取)。 但是想想内存空间是有限的,所以必须有一些规则来管理缓存的使用,而LRU(Least Recently Used) Cache就是其中之一,直接翻译就是“最不经常使用的数据,重要性是最低的,应该优先删除”。 需求分析 假设我
JSBridge是什么?
Posted on:2024年8月10日 at 17:05JSBridge(JavaScript Bridge)是一种用于连接不同技术平台和语言的桥梁,它允许JavaScript代码与原生应用程序(如Android和iOS应用)进行交互。以下是关于JSBridge的详细解释: 定义 JSBridge是一种桥接器,通过JS引擎或Webview容器为媒介,约定协议进行通信,实现Native端(原生应用)和Web端(如HTML5页面)双向通信的一种机制。 它的
CSR和SSR分别是什么?
Posted on:2024年8月10日 at 17:05在前端开发中,CSR(Client-Side Rendering,客户端渲染)和SSR(Server-Side Rendering,服务器端渲染)是两种常见的页面渲染技术,它们各自有不同的特点和应用场景。 1. CSR(客户端渲染) 客户端渲染(Client-Side Rendering)是指网页的HTML结构、CSS样式和JavaScript代码等全部或部分由用户的浏览器在接收到服务器发送的原始
typeof 是否能正确判断类型?
Posted on:2024年8月10日 at 17:05对于原始类型来说,除了 null 都可以调用typeof显示正确的类型。 typeof 1 // 'number' typeof '1' // 'string' typeof undefined // 'undefined' typeof true // 'boolean' typeof Symbol() // 'symbol' 但对于引用数据类型,除了函数之外,都会显示"object"。 typ
什么是内存泄漏?什么原因会导致呢?
Posted on:2024年8月10日 at 17:05内存泄露的解释:程序中己动态分配的堆内存由于某种原因未释放或无法释放。 根据JS的垃圾回收机制,当内存中引用的次数为0的时候内存才会被回收 全局执行上下文中的对象被标记为不再使用才会被释放 内存泄露的几种场景 全局变量过多。通常是变量未被定义或者胡乱引用了全局变量 // main.js // 场景1 function a(){ b=10; } a(); b++; // 场景2 setTimeout
什么是跨域?
Posted on:2024年8月10日 at 17:04跨域(Cross-Origin)是指从一个域名的网页去请求另一个域名的资源。在Web开发中,出于安全考虑,同源策略(Same-Origin Policy)限制了文档或脚本如何与来自不同源的“资源”进行交互。这里的“源”指的是协议(如http或https)、域名(如www.example.com)和端口号(如80或443)的组合。如果协议、域名或端口号中的任何一个不同,那么两个资源就被认为是来自不同
Axios的原理是什么?
Posted on:2024年8月10日 at 17:04一、axios的使用 关于axios的基本使用,上篇文章已经有所涉及,这里再稍微回顾下: 发送请求 import axios from 'axios'; axios(config) // 直接传入配置 axios(url[, config]) // 传入url和配置 axios[method](url[, option]) // 直接调用请求方式方法,传入url和配置 axios[method](
说说你对SPA的理解
Posted on:2024年8月10日 at 17:04一、什么是SPA SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加
web常见的攻击方式有哪些,以及如何进行防御?
Posted on:2024年8月10日 at 17:04一、是什么 Web攻击(WebAttack)是针对用户上网行为或网站服务器等设备进行攻击的行为 如植入恶意代码,修改网站权限,获取网站用户隐私信息等等 Web应用程序的安全性是任何基于Web业务的重要组成部分 确保Web应用程序安全十分重要,即使是代码中很小的 bug 也有可能导致隐私信息被泄露 站点安全就是为保护站点不受未授权的访问、使用、修改和破坏而采取的行为或实践 我们常见的Web攻击方式有
说说你对函数式编程的理解,以及优缺点?
Posted on:2024年8月10日 at 17:04一、是什么 函数式编程是一种"编程范式"(programming paradigm),一种编写程序的方法论 主要的编程范式有三种:命令式编程,声明式编程和函数式编程 相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而非设计一个复杂的执行过程 举个例子,将数组每个元素进行平方操作,命令式编程与函数式编程如下 // 命令
说说 JavaScript 中内存泄漏有哪几种情况?
Posted on:2024年8月10日 at 17:04一、是什么 内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存 并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费 程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存 对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,
举例说明你对尾递归的理解,以及有哪些应用场景
Posted on:2024年8月10日 at 17:04一、递归 递归(英语:Recursion) 在数学与计算机科学中,是指在函数的定义中使用函数自身的方法 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数 其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解 一般来说,递归需要有边界条件、递归前进阶段和递归返回阶段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回 下面实现一个函
说说你对事件循环的理解
Posted on:2024年8月10日 at 17:04一、是什么 JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事 为什么要这么设计,跟JavaScript的应用场景有关 JavaScript 初期作为一门浏览器脚本语言,通常用于操作 DOM ,如果是多线程,一个线程进行了删除 DOM ,另一个添加 DOM,此时浏览器该如何处理? 为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种
什么是事件代理,以及它的应用场景有哪些?
Posted on:2024年8月10日 at 17:04一、是什么 事件代理,俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素 前面讲到,事件流的都会经过三个阶段: 捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就是在冒泡阶段完成 事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素 当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层
说说new操作符具体干了什么?
Posted on:2024年8月10日 at 17:04一、是什么 在JavaScript中,new操作符用于创建一个给定构造函数的实例对象 例子 function Person(name, age){ this.name = name; this.age = age; } Person.prototype.sayName = function () { console.log(this.name) } const person1 = new Pers
正则表达式是什么,有哪些应用场景?
Posted on:2024年8月10日 at 17:04一、是什么 正则表达式是一种用来匹配字符串的强有力的武器 它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的 在 JavaScript中,正则表达式也是对象,构建正则表达式有两种方式: 字面量创建,其由包含在斜杠之间的模式组成 const re = /\d+/g; 调用RegExp对象的构造函数 const re = new Re
typeof 与 instanceof 有什么区别
Posted on:2024年8月10日 at 17:04一、typeof typeof 操作符返回一个字符串,表示未经计算的操作数的类型 使用方法如下: typeof operand typeof(operand) operand表示对象或原始值的表达式,其类型将被返回 举个例子 typeof 1 // 'number' typeof '1' // 'string' typeof undefined // 'undefined' typeof true
JavaScript中的事件模型有哪些
Posted on:2024年8月10日 at 17:04一、事件与事件流 javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等 由于DOM是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事件流的概念 事件流都会经历三个阶段: 事件捕获阶段(capture phase) 处于目标阶段(target phase)
JavaScript中执行上下文和执行栈是什么?
Posted on:2024年8月10日 at 17:04一、执行上下文 简单的来说,执行上下文是一种对Javascript代码执行环境的抽象概念,也就是说只要有Javascript代码运行,那么它就一定是运行在执行上下文中 执行上下文的类型分为三种: 全局执行上下文:只有一个,浏览器中的全局对象就是 window 对象,this 指向这个全局对象 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文 Ev
JavaScript中的原型,原型链分别是什么?
Posted on:2024年8月10日 at 17:04一、原型 JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象 当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾 准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非实例对象本身
什么是作用域链?
Posted on:2024年8月10日 at 17:04作用域链(Scope Chain)是 JavaScript 中用于查找变量和函数的一种机制。每个 JavaScript 函数都会创建一个作用域链。 作用域链是由当前执行环境(Execution Context)中的变量对象(Variable Object)以及其父级执行环境的变量对象组成的。当代码在一个执行环境中执行时,如果需要访问一个变量或者函数,JavaScript 引擎会首先在当前执行环境的
说说你对闭包的理解,以及闭包使用场景
Posted on:2024年8月10日 at 17:04一、是什么 一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure) 也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域 在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁 下面给出一个简单的例子 function ini
你是怎么理解ES6中Module的?使用场景有哪些?
Posted on:2024年8月10日 at 17:04一、介绍 模块,(Module),是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体)。 两个基本的特征:外部特征和内部特征 外部特征是指模块跟外部环境联系的接口(即其他模块或程序调用该模块的方式,包括有输入输出参数、引用的全局变量)和模块的功能 内部特征是指模块的内部环境具有的特点(即该模块的局部数据和程序代码) 为什么需要模块化 代码抽象 代码封装 代码复用 依赖
== 和 ===有什么区别,分别在什么情况使用?
Posted on:2024年8月10日 at 17:04一、等于操作符 等于操作符用两个等于号( == )表示,如果操作数相等,则会返回 true 前面文章,我们提到在JavaScript中存在隐式转换。等于操作符(==)在比较中会先进行类型转换,再确定操作数是否相等 遵循以下规则: 如果任一操作数是布尔值,则将其转换为数值再比较是否相等 let result1 = (true == 1); // true 如果一个操作数是字符串,另一个操作数是数值,
你是怎么理解ES6中 Promise的?使用场景有哪些?
Posted on:2024年8月10日 at 17:04一、介绍 Promise ,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大 在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码 doSomething(function(result) { doSomethingElse(result, function(newResult) { doThirdThing(newResult, function(
var、let、const之间有什么区别?
Posted on:2024年8月10日 at 17:04一、var 在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量 注意:顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象 var a = 10; console.log(window.a) // 10 使用var声明的变量存在变量提升的情况 console.log(a) // undefined var a = 20 在编译阶
'1'.toString()为什么不会报错?
Posted on:2024年7月22日 at 11:51其实在这个语句运行的过程中做了这样几件事情: var s = new Object('1'); s.toString(); s = null; 第一步: 创建Object类实例。注意为什么不是String ? 由于Symbol和BigInt的出现,对它们调用new都会报错,目前ES6规范也不建议用new来创建基本类型的包装类。 第二步: 调用实例方法。 第三步: 执行完方法立即销毁这个实例。 整个
说说ajax的原理,以及如何实现?
Posted on:2024年7月22日 at 11:26一、是什么 AJAX 全称(Async Javascript and XML) 即异步的 JavaScript 和 XML,是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页 Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面 流程图如下: 下面
谈谈你知道的DOM常见的操作
Posted on:2024年7月22日 at 11:21一、DOM 文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口 它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容 任何 HTML 或XML文档都可以用 DOM 表示为一个由节点构成的层级结构 节点分很多类型,每种类型对应着文档中不同的信息和(或)标记,也都有自己不同的特性、数据和方法,而且与其他类型有某种关系,如下所示:
说说你对BOM的理解,以及常见的BOM对象有哪些?
Posted on:2024年7月22日 at 11:19一、是什么 BOM (Browser Object Model),浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象 其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退,前进,刷新,浏览器的窗口发生变化,滚动条的滚动,以及获取客户的一些信息如:浏览器品牌版本,屏幕分辨率 浏览器的全部内容可以看成DOM,整个浏览器可以看成BOM。区别如下: 二、window Bom的核心对象是wind
Javascript本地存储的方式有哪些,有什么区别,及有哪些应用场景?
Posted on:2024年7月22日 at 11:14一、方式 javaScript本地缓存的方法我们主要讲述以下四种: cookie sessionStorage localStorage indexedDB cookie Cookie,类型为「小型文本文件」,指某些网站为了辨别用户身份而储存在用户本地终端上的数据。是为了解决 HTTP 无状态导致的问题 作为一段一般不超过 4KB 的小型文本数据,它由一个名称(Name)、一个值(Value)和其
Javascript中如何实现函数缓存?函数缓存有哪些应用场景?
Posted on:2024年7月22日 at 11:07一、是什么 函数缓存,就是将函数运算过的结果进行缓存 本质上就是用空间(缓存存储)换时间(计算过程) 常用于缓存数据计算结果和缓存对象 const add = (a,b) => a+b; const calc = memoize(add); // 函数缓存 calc(10,20);// 30 calc(10,20);// 30 缓存 缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能
什么是防抖和节流,以及如何编码实现?
Posted on:2024年7月22日 at 11:06一、是什么 本质上是优化高频率执行代码的一种手段 如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能 为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(节流)和debounce(防抖)的方式来减少调用频率 定义 节流: n 秒内只运行一次,若在 n 秒内重
Object.is和===有什么区别?
Posted on:2024年7月22日 at 10:55Object在严格等于的基础上修复了一些特殊情况下的失误,具体来说就是+0和-0,NaN和NaN。 源码如下: function is(x, y) { if (x === y) { //运行到1/x === 1/y的时候x和y都为0,但是1/+0 = +Infinity, 1/-0 = -Infinity, 是不 一样的 return x !== 0 || y !== 0 || 1 / x ===
微前端可以解决什么问题?
Posted on:2024年7月22日 at 10:54任何新技术的产生都是为了解决现有场景和需求下的技术痛点,微前端也不例外: 拆分和细化 当下前端领域,单页面应用(SPA)是非常流行的项目形态之一,而随着时间的推移以及应用功能的丰富,单页应用变得不再单一而是越来越庞大也越来越难以维护,往往是改一处而动全身,由此带来的发版成本也越来越高。微前端的意义就是将这些庞大应用进行拆分,并随之解耦,每个部分可以单独进行维护和部署,提升效率。 整合历史系统 在不
实现微前端有哪些技术方案?
Posted on:2024年7月22日 at 10:54单纯根据对概念的理解,很容易想到实现微前端的重要思想就是将应用进行拆解和整合,通常是一个父应用加上一些子应用,那么使用类似Nginx配置不同应用的转发,或是采用iframe来将多个应用整合到一起等等这些其实都属于微前端的实现方案: Nginx路由转发 通过Nginx配置反向代理来实现不同路径映射到不同应用,例如www.abc.com/app1对应app1,www.abc.com/app2对应app
什么是 PWA?
Posted on:2024年7月22日 at 10:52PWA的中文名叫做渐进式网页应用,早在2014年, W3C 公布过 Service Worker 的相关草案,但是其在生产环境被 Chrome 支持是在 2015 年。因此,如果我们把 PWA 的关键技术之一 Service Worker 的出现作为 PWA 的诞生时间,那就应该是 2015 年。 自 2015 年以来,PWA 相关的技术不断升级优化,在用户体验和用户留存两方面都提供了非常好的解决
Service worker是什么?
Posted on:2024年7月22日 at 10:52service worker是PWA的重要组成部分,W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存,也是Web Worker的升级版。 Service worker (简称 SW) 是一个注册在指定源和路径下的事件驱动 Worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请
箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?
Posted on:2024年7月22日 at 10:52什么是箭头函数? ES6中允许使用箭头=>来定义箭头函数,具体语法,我们来看一个简单的例子: // 箭头函数 let fun = (name) => { // 函数体 return `Hello ${name} !`; }; // 等同于 let fun = function (name) { // 函数体 return `Hello ${name} !`; }; 可以看出,定义箭头函在数语法上要
什么是变量提升
Posted on:2024年7月22日 at 10:52函数在运行的时候,会首先创建执行上下文,然后将执行上下文入栈,然后当此执行上下文处于栈顶时,开始运行执行上下文。 在创建执行上下文的过程中会做三件事:创建变量对象,创建作用域链,确定 this 指向,其中创建变量对象的过程中,首先会为 arguments 创建一个属性,值为 arguments,然后会扫码 function 函数声明,创建一个同名属性,值为函数的引用,接着会扫码 var 变量声明,
JS代码中的use strict是什么意思?
Posted on:2024年7月22日 at 10:52use strict是一种ECMAscript5添加的(严格)运行模式,这种模式使得Javascript 在更严格的条件下运行。 设立"严格模式"的目的,主要有以下几个: 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;消除代码运行的一些不安全之处,保证代码运行的安全; 提高编译器效率,增加运行速度; 为未来新版本的Javascript 做好铺垫。 区别: 禁止使用with
“严格模式”是什么?
Posted on:2024年7月22日 at 10:52除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。 设立"严格模式"的目的,主要有以下几个: - 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全之处,保证代码运行的安全; - 提高编译器效率,增加运行速度; - 为未来新版本的
js对象中,可枚举性(enumerable)是什么?
Posted on:2024年7月22日 at 10:12可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中(除非属性名是一个Symbol)。具体来说,如果一个属性的enumerable为false,下面三个操作不会取到该属性。 for..in循环 Object.keys方法 JSON.stringify方法 var o = { a: 1, b: 2 }; o.c = 3; Object.defineProper
如何实现浏览器内多个标签页之间的通信?
Posted on:2024年7月22日 at 10:09Broadcast Channel 顾名思义,“广播频道”,官方文档里的解释为“用于同源不同页面之间完成通信的功能”,在其中某个页面发送的消息会被其他页面监听到。 注意“同源”二字,该方法无法完成跨域的数据传输。 localStorage localStorage是浏览器多个标签共用的存储空间,所以可以用来实现多标签之间的通信(ps:session是会话级的存储空间,每个标签页都是单独的)。 Sh
Javascript字符串的常用方法有哪些?
Posted on:2024年7月20日 at 18:39一、操作方法 我们也可将字符串常用的操作方法归纳为增、删、改、查,需要知道字符串的特点是一旦创建了,就不可变 增 这里增的意思并不是说直接增添内容,而是创建字符串的一个副本,再进行操作 除了常用+以及${}进行字符串拼接之外,还可通过concat concat 用于将一个或多个字符串拼接成一个新字符串 let stringValue = "hello "; let result = stringV
Javscript数组的常用方法有哪些?
Posted on:2024年7月20日 at 18:39以下是一些常见的JavaScript数组方法: push(): 在数组末尾添加一个或多个元素,并返回新数组的长度。 pop(): 移除并返回数组末尾的元素。 unshift(): 在数组开头添加一个或多个元素,并返回新数组的长度。 shift(): 移除并返回数组开头的元素。 concat(): 合并两个或更多数组,并返回新的合并后的数组,不会修改原始数组。 slice(): 从数组中提取指定位置
为什么JavaScript是单线程?
Posted on:2024年7月20日 at 18:23JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。 JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上
base64编码图片,为什么会让数据量变大?
Posted on:2024年7月20日 at 18:19Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在
如何使用js计算一个html页面有多少种标签?
Posted on:2024年7月20日 at 18:17分析 这道题看似简单,但是是一个很有价值的一道题目。它包含了很多重要的知识: 如何获取所有DOM节点 伪数组如何转为数组 去重 解答 获取所有的DOM节点。 document.querySelectorAll('*') 此时得到的是一个NodeList集合,我们需要将其转化为数组,然后对其筛选。 转化为数组 [...document.querySelectorAll('*')] 一个拓展运算符就轻
什么是类数组对象?
Posted on:2024年7月20日 at 18:09一个拥有 length 属性和若干索引属性的对象就可以被称为类数组对象,类数组对象和数组类似,但是不能调用数组的方法。常见的类数组对象有 arguments 和 DOM 方法的返回结果,还有一个函数也可以被看作是类数组对象,因为它含有 length 属性值,代表可接收的参数个数。 常见的类数组转换为数组的方法有这样几种: (1)通过 call 调用数组的 slice 方法来实现转换 Array.p
遍历一个任意长度的list中的元素并依次创建异步任务,如何获取所有任务的执行结果?
Posted on:2024年7月20日 at 17:43看到这个题目,大家首先想到的是 Promise.all 或者 Promise.allSettled。 Promise.all Promise.all 需要传入一个数组,数组中的元素都是 Promise 对象。当这些对象都执行成功时,则 all 对应的 promise 也成功,且执行 then 中的成功回调。如果有一个失败了,则 all 对应的 promise 失败,且失败时只能获得第一个失败 Pr
实现以下转换,合并连续的数字
Posted on:2024年7月20日 at 17:42[1,2,3,4,6,7,9,13,15]=>['1->4','6->7','9','13','15'] 本题是一道比较简单的数组处理题目,主要有两个处理步骤: 将超过一个的连续数字元素,合并成 x->y,比如 [1,2,3,4] 转成 ['1->4'] 将非连续的数字元素,转成字符串 具体的实现代码如下: function shortenArray(arr) { // 处理边界 if (!Arr
怎么使用 js 动态生成海报?
Posted on:2024年7月20日 at 17:40比如将当前页面生成一张海报,要求携带当前用户的登录信息。 方案一:DOM->canvas->image 将目标 DOM 节点绘制到 canvas 画布,然后利用 canvas 相关的 API 以图片形式导出。 可简单标记为绘制阶段和导出阶段两个步骤: 绘制阶段:选择希望绘制的 DOM 节点,根据 DOM 的 nodeType 属性调用 canvas 对象的对应 API,将目标 DOM 节点绘制到
以下等式是成立的吗:1_000_000 === 1000000 ?
Posted on:2024年7月20日 at 17:291_000_000 === 1000000 的结果为 true 1_000_000 中使用了 _,这是数字分隔符规范(Numeric Separators),也就是允许在数字值中使用下划线来提高数值的可读性。 如果我们尝试写十亿这样的值,可以通过用下划线分隔数字来提高可读性。 let a = 1000000000000; let b = 1_000_000_000_000; console.log
写出一个函数trans,将数字转换成汉语的输出,输入为不超过10000亿的数字。
Posted on:2024年7月20日 at 17:28trans(123456) —— 十二万三千四百五十六 trans(100010001)—— 一亿零一万零一 23.12.18 更新,有同学投稿提供了自己的答案,更加简洁 function NumToChina(n) { n = n.toString(); let numbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; if (n
123['toString'].length + 123 的输出值是多少?
Posted on:2024年7月20日 at 11:58function的length function fn1 (name) {} function fn2 (name = '林三心') {} function fn3 (name, age = 22) {} function fn4 (name, age = 22, gender) {} function fn5(name = '林三心', age, gender) { } console.log(
使用Promise实现每隔1秒输出1,2,3
Posted on:2024年7月20日 at 11:58这道题比较简单的一种做法是可以用Promise配合着reduce不停的在promise后面叠加.then,请看下面的代码: const arr = [1, 2, 3] arr.reduce((p, x) => { return p.then(() => { return new Promise(r => { setTimeout(() => r(console.log(x)), 1000) })
null 和 undefined 有什么区别?
Posted on:2024年7月20日 at 11:57首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。 undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。 undefined 在 JavaScript 中不是一个保留字,这意味着
object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别是什么?
Posted on:2024年7月20日 at 11:57扩展运算符 let outObj = { inObj: {a: 1, b: 2} } let newObj = {...outObj} newObj.inObj.a = 2 console.log(outObj) // {inObj: {a: 2, b: 2}} Object.assign() let outObj = { inObj: {a: 1, b: 2} } let newObj = O
如果new一个箭头函数会怎么样?
Posted on:2024年7月20日 at 11:56箭头函数是ES6中的提出来的,它没有prototype,也没有自己的this指向,更不可以使用arguments参数,所以不能New一个箭头函数。 new操作符的实现步骤如下: 1、创建一个空的简单JavaScript对象(即{}); 2、为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ; 3、将步骤1新创建的对象作为this的上下文 ; 4、如果该函数没有返回对
箭头函数的 this 指向哪⾥?
Posted on:2024年7月20日 at 11:56箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以是不会被new调⽤的,这个所谓的this也不会被改变。 可以⽤Babel理解⼀下箭头函数: // ES6 const obj = { getArrow() { return () => { console
JavaScript脚本延迟加载的方式有哪些?
Posted on:2024年7月20日 at 11:55延迟加载就是等页面加载完成之后再加载 JavaScript 文件。 js 延迟加载有助于提高页面加载速度。 一般有以下几种方式: defer 属性: 给 js 脚本添加 defer 属性,这个属性会让脚本的加载与文档的解析同步解析,然后在文档解析完成后再执行这个脚本文件,这样的话就能使页面的渲染不被阻塞。多个设置了 defer 属性的脚本按规范来说最后是顺序执行的,但是在一些浏览器中可能不是这样。
浏览器的垃圾回收机制有哪些?
Posted on:2024年7月20日 at 11:53JS会在创建变量时自动分配内存,在不使用的时候会自动周期性的释放内存,释放的过程就叫 "垃圾回收"。 一方面自动分配内存减轻了开发者的负担,开发者不用过多的去关注内存使用,但是另一方面,正是因为因为是自动回收,所以如果不清楚回收的机制,会很容易造成混乱,而混乱就很容易造成"内存泄漏"。 由于是自动回收,所以就存在一个 "内存是否需要被回收的" 的问题,但是这个问题的判定在程序中意味着无法通过某个算
浏览器的同源策略是什么?
Posted on:2024年7月20日 at 11:49同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。 它的核心就在于它认为自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意
js中如何判断一个值是否是数组类型?
Posted on:2024年7月20日 at 11:47instanceof const arr= []; arr instanceof Array; // true Array.isArray const arr = [] Array.isArray(arr) // true const obj = {} Array.isArray(obj) // false Object.prototype.isPrototypeOf 使用Object的原型方法i
JS中怎么阻止事件冒泡和默认事件?
Posted on:2024年7月20日 at 11:42event.stopPropagation()方法 这是阻止事件的冒泡方法,不让事件向 document 上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开, event.preventDefault()方法 这是阻止默认事件的方法,比如在a标签的绑定事件上调用此方法,链接则不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素; return fals
setTimeout 为什么不能保证能够及时执行?
Posted on:2024年7月20日 at 11:33主线程从任务队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop。 setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。 浏览器的JS引擎遇到setTimeout,拿走之后不会立即放入异步队列,同步任务执行之后,timer模块会到设置时间之后放到异步队列中。js引擎发现同步队列中没有要执行的东西了,即运行栈空
移动端的点击事件的有延迟,时间是多久,为什么会有? 怎么解决这个延时?
Posted on:2024年7月20日 at 11:32移动端点击有 300ms 的延迟是因为移动端会有双击缩放的这个操作,因此浏览器在 click 之后要等待 300ms,看用户有没有下一次点击,来判断这次操作是不是双击。 有三种办法来解决这个问题: 通过 meta 标签禁用网页的缩放。 通过 meta 标签将网页的 viewport 设置为 ideal viewport。 调用一些 js 库,比如 FastClick click 延时问题还可能引起
什么是点击穿透,怎么解决?
Posted on:2024年7月20日 at 11:30在发生触摸动作约300ms之后,移动端会模拟产生click动作,它底下的具有点击特性的元素也会被触发,这种现象称为点击穿透。 常见场景 情景一:蒙层点击穿透问题,点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件。 情景二:跨页面点击穿透问题:如果按钮下面恰好是一个有href属性的a标签,那么页面就会发生跳转。 情景三:另一种跨页面点击穿透问题:这次没有mask了,
js 中的倒计时,怎么实现纠正偏差?
Posted on:2024年7月20日 at 11:19在前端实现中我们一般通过 setTimeout 和 setInterval 方法来实现一个倒计时效果。但是使用这些方法会存在时间偏差的问题,这是由于 js 的程序执行机制造成的,setTimeout 和 setInterval 的作用是隔一段时间将回调事件加入到事件队列中,因此事件并不是立即执行的,它会等到当前执行栈为空的时候再取出事件执行,因此事件等待执行的时间就是造成误差的原因。 一般解决倒计
实现mergePromise函数
Posted on:2024年7月20日 at 11:10实现mergePromise函数,把传进去的数组按顺序先后执行,并且把返回的数据先后放到数组data中。 const time = (timer) => { return new Promise(resolve => { setTimeout(() => { resolve() }, timer) }) } const ajax1 = () => time(2000).then(() => { c
使用Promise实现:限制异步操作的并发个数,并尽可能快的完成全部
Posted on:2024年7月20日 at 11:10有8个图片资源的url,已经存储在数组urls中。 urls类似于['https://image1.png', 'https://image2.png', ....] 而且已经有一个函数function loadImg,输入一个url链接,返回一个Promise,该Promise在图片下载完成的时候resolve,下载失败则reject。 但有一个要求,任何时刻同时下载的链接数量不可以超过3个。
写一个 repeat 方法,实现字符串的复制拼接
Posted on:2024年7月20日 at 11:10实现的方法有很多,以下介绍几种。 方法一 空数组 join function repeat(target, n) { return (new Array(n + 1)).join(target); } 方法二 改良方法1,省去创建数组这一步,提高性能。之所以创建一个带 length 属性的对象,是因为要调用数组的原型方法,需要指定 call 第一个参数为类数组对象。 function repeat
【Promise第四题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01const promise1 = new Promise((resolve, reject) => { console.log('promise1') resolve('resolve1') }) const promise2 = promise1.then(res => { console.log(res) }) console.log('1', promise1); console.log('
【Promise第八题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01const promise = new Promise((resolve, reject) => { console.log(1); setTimeout(() => { console.log("timerStart"); resolve("success"); console.log("timerEnd"); }, 0); console.log(2); }); promise.then((r
【Promise第九题】下面两段代码分别输出什么?
Posted on:2024年7月20日 at 11:01代码一: setTimeout(() => { console.log('timer1'); setTimeout(() => { console.log('timer3') }, 0) }, 0) setTimeout(() => { console.log('timer2') }, 0) console.log('start') 代码二: setTimeout(() => { console.
【Promise第10题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01Promise.resolve().then(() => { console.log('promise1'); const timer2 = setTimeout(() => { console.log('timer2') }, 0) }); const timer1 = setTimeout(() => { console.log('timer1') Promise.resolve().then
【Promise第11题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('success') }, 1000) }) const promise2 = promise1.then(() => { throw new Error('error!!!') }) console.log('promise1', prom
【Promise第23题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01Promise.resolve('1') .then(res => { console.log(res) }) .finally(() => { console.log('finally') }) Promise.resolve('2') .finally(() => { console.log('finally2') return '我是finally2返回的值' }) .then(res =>
【Promise第24题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01function promise1 () { let p = new Promise((resolve) => { console.log('promise1'); resolve('1') }) return p; } function promise2 () { return new Promise((resolve, reject) => { reject('error') }) } pro
【Promise第28题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } async1(); console.log('start') 解析 首先一进来是创建了两个函数的,
【Promise第38题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01const first = () => (new Promise((resolve, reject) => { console.log(3); let p = new Promise((resolve, reject) => { console.log(7); setTimeout(() => { console.log(5); resolve(6); console.log(p) }, 0) r
【Promise第40题】下面代码的输出是什么?
Posted on:2024年7月20日 at 11:01const p1 = new Promise((resolve) => { setTimeout(() => { resolve('resolve3'); console.log('timer1') }, 0) resolve('resovle1'); resolve('resolve2'); }).then(res => { console.log(res) setTimeout(() => {
说说下面代码执行后的输出是什么?
Posted on:2024年7月20日 at 11:00var b = 10; (function b(){ b = 20; console.log(b); })(); 先看浏览器中的执行结果: 解析 代码预解析时,会将var b进行变量提升,此时b没有被赋值(b=undefined) (这里有人会说这里明明有个函数表达式呀,为什么没有进入变量提升,因为IIFE自带有词法作用域(我们常理解得作用域)) 发现没有可以变量提升得时候将b赋值为10,此时会将
下面代码的输出是什么?
Posted on:2024年7月20日 at 11:00console.log(typeof typeof typeof null); console.log(typeof console.log(1)); 第一行代码输出结果为 "string"。解释如下: typeof null 返回 "object",因为在JavaScript中,null 被认为是一个空对象引用。 typeof "object" 返回 "string"。 typeof "stri
使用js实现二分查找
Posted on:2024年7月20日 at 10:57二分查找,也称为折半查找,是指在有序的数组里找出指定的值,返回该值在数组中的索引。 查找步骤如下: 从有序数组的最中间元素开始查找,如果该元素正好是指定查找的值,则查找过程结束。否则进行下一步; 如果指定要查找的元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作; 重复以上过程,直到找到目标元素的索引,查找成功;或者直到子数组为空,查找失败。 优点是比较次数
下面代码会输出什么?
Posted on:2024年7月20日 at 10:39foo(); var foo; function foo(){ console.log(1); } foo = function(){ console.log(2); } 答案是:1 函数声明和变量声明都会被提升,但是有一个值得注意的细节,那就是,函数会首先提升,然后才是变量! 根据 JavaScript 的变量和函数提升规则,上述代码在执行时会被解析成以下形式: function foo(){
如何确保你的构造函数只能被new调用,而不能被普通调用?
Posted on:2024年7月20日 at 10:39明确函数的双重用途 JavaScript 中的函数一般有两种使用方式: 当作构造函数使用: new Func() 当作普通函数使用: Func() 但 JavaScript 内部并没有区分两者的方式,我们人为规定构造函数名首字母要大写作为区分。也就是说,构造函数被当成普通函数调用不会有报错提示。 下面来举个栗子: // 定义构造函数 Person function Person(firstName
岛屿数量
Posted on:2024年7月20日 at 10:37给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包围。 示例 1: 输入: grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0",
promise.catch后面的.then还会执行吗?
Posted on:2024年7月20日 at 10:36答案: 会继续执行。 虽然Promise是开发过程中使用非常频繁的一个技术点,但是它的一些细节可能很多人都没有去关注过。我们都知道.then, .catch, .finally都可以链式调用,其本质上是因为返回了一个新的Promise实例。 catch的语法形式如下: p.catch(onRejected); .catch只会处理rejected的情况,并且也会返回一个新的Promise实例。 .
如何区分数组和对象?
Posted on:2024年7月20日 at 10:31方法1 :通过 ES6 中的 Array.isArray 来识别 console.log(Array.isArray([]))//true console.log(Array.isArray({}))//false 方法2 :通过 instanceof 来识别 console.log([] instanceof Array)//true console.log({} instanceof Arra
实现一个数字转中文的方法
Posted on:2024年7月20日 at 09:49//阿拉伯数字转中文数字 function NoToChinese(num) { if (!/^\d*(\.\d*)?$/.test(num)) { alert("Number is wrong!"); return "Number is wrong!"; } var AA = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
ES6中新增的Set、Map两种数据结构怎么理解?
Posted on:2024年7月20日 at 09:48如果要用一句来描述,我们可以说 Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构 什么是集合?什么又是字典? 集合是由一堆无序的、相关联的,且不重复的内存结构【数学中称为元素】组成的组合 字典是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各不相同 区别? 共同点:集合、字典都可以存储不重复的值 不同点:集合是以[值,值]的形式存储元素,字典是以[键,值]的形式存
ES6中函数新增了哪些扩展?
Posted on:2024年7月20日 at 09:43一、参数 ES6允许为函数的参数设置默认值 function log(x, y = 'World') { console.log(x, y); } console.log('Hello') // Hello World console.log('Hello', 'China') // Hello China console.log('Hello', '') // Hello 函数的形参是默认声明的
ES6中对象新增了哪些扩展?
Posted on:2024年7月20日 at 09:42一、属性的简写 ES6中,当对象键名与对应值名相等的时候,可以进行简写 const baz = {foo:foo} // 等同于 const baz = {foo} 方法也能够进行简写 const o = { method() { return "Hello!"; } }; // 等同于 const o = { method: function() { return "Hello!"; } } 在
你是怎么理解ES6中Proxy的?使用场景有哪些?
Posted on:2024年7月20日 at 09:39一、介绍 定义: 用于定义基本操作的自定义行为 本质: 修改的是程序默认形为,就形同于在编程语言层面上做修改,属于元编程(meta programming) 元编程(Metaprogramming,又译超编程,是指某类计算机程序的编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作 一段代码来理解 #!/bin/bash # metapro
你是怎么理解ES6中 Decorator 的?使用场景有哪些?
Posted on:2024年7月20日 at 08:58一、介绍 Decorator,即装饰器,从名字上很容易让我们联想到装饰者模式 简单来讲,装饰者模式就是一种在不改变原类和使用继承的情况下,动态地扩展对象功能的设计理论。 ES6中Decorator功能亦如此,其本质也不是什么高大上的结构,就是一个普通的函数,用于扩展类属性和类方法 这里定义一个士兵,这时候他什么装备都没有 class soldier{ } 定义一个得到 AK 装备的函数,即装饰器
Js 动画与 CSS 动画区别及相应实现
Posted on:2024年7月19日 at 16:00CSS3 的动画的优点 在性能上会稍微好一些,浏览器会对 CSS3 的动画做一些优化 代码相对简单 缺点 在动画控制上不够灵活 兼容性不好 JavaScript 的动画正好弥补了这两个缺点,控制能力很强,可以单帧的控制、变换,同时写得好完全可以兼容 IE6,并且功能强大。对于一些复杂控制的动画,使用 javascript 会比较靠谱。而在实现一些小的交互动效的时候,就多考虑考虑 CSS 吧
Promise 的 finally 怎么实现的?
Posted on:2024年7月19日 at 13:41Promise.prototype.finally 方法是 ES2018 引入的一个方法,用于在 Promise 执行结束后无论成功与否都会执行的操作。在实际应用中,finally 方法通常用于释放资源、清理代码或更新 UI 界面等操作。 以下是一个简单的实现方式: Promise.prototype.finally = function(callback) { const P = this.co
说说你对 webpack5 模块联邦的了解?
Posted on:2024年7月19日 at 13:35Webpack 5 的模块联邦(Module Federation)是一种新的技术,可以实现多个独立 Webpack 构建之间的共享模块和代码。它通过让每个构建的应用程序能够使用其他应用程序中的模块来提高代码共享和复用的效率。 Module Federation 基于 webpack 的远程容器特性。它允许将一个应用程序的某些模块打包为一个独立的、可远程加载的 bundle,并在运行时动态地加载这
前端的页面截图怎么实现?
Posted on:2024年7月19日 at 10:58前端实现页面截图主要有以下几种方式: 使用浏览器自带的截图功能:在 Chrome 浏览器中,可以通过右键菜单或者快捷键 Ctrl + Shift + P 打开“命令菜单”,然后输入“截图”并选择相应选项即可。 使用第三方插件或工具:例如 Awesome Screenshot、Nimbus Screenshot 等浏览器插件,或者 html2canvas、dom-to-image 等 JavaScr
如果要实现一个类似“谷歌图片”的系统,你会有哪些方面的考虑?
Posted on:2024年7月19日 at 10:47可以从以下几个方面考虑: 设计界面和交互:首先需要设计一个美观、易用的用户界面,包括搜索框、图片展示区、分页、筛选器等。同时还需要设计一些交互细节,例如图片加载过程中的占位符、无结果时的提示信息、图片缩放和拖拽等。 数据获取和处理:接下来需要考虑如何获取和处理图片数据。可以使用爬虫技术从其他网站抓取图片,也可以通过图片 API 或者图库合作获得。在获取到图片之后,还需要对其进行处理,例如压缩、裁剪
前端路由 `a -> b -> c`这样前进,也可以返回 `c -> b -> a`,用什么数据结构来存比较高效
Posted on:2024年7月19日 at 10:44在前端路由中,常用的存储方式是栈(Stack)数据结构。栈是一种线性数据结构,具有后进先出(LIFO)的特点,即最后入栈的元素最先弹出栈。 当用户访问一个新页面时,可以将当前页面路由信息压入栈中。例如,在访问页面 a 时,可以将 a 的路由信息存储在栈顶。当用户访问 b 页面时,再将 b 的路由信息压入栈中,此时 a 的路由信息就被挤到了栈底。以此类推,当用户访问 c 页面时,c 的路由信息被压入
导致 JavaScript 中 this 指向混乱的原因是什么?
Posted on:2024年7月19日 at 10:43JavaScript 中 this 指向混乱的原因主要有以下几点: 函数调用方式不同:JavaScript 中函数的调用方式有多种,包括普通函数调用、方法调用、构造函数调用和箭头函数等。不同的调用方式会导致 this 的指向不同。 丢失绑定:当一个函数被单独调用时,即没有任何对象或上下文与之相关联时,this 将指向全局对象(在浏览器环境中通常是 window 对象)。这种情况下,如果函数内部使用
为什么要区分宏任务和微任务?它们的执行优先级是什么?
Posted on:2024年7月19日 at 10:43宏任务(macrotask)和微任务(microtask)的区分主要是为了解决 JavaScript 引擎中不同任务之间的执行优先级问题。 宏任务通常包括以下几种: setTimeout 和 setInterval 定时器 DOM 事件处理程序 AJAX 请求的回调函数 script 标签的加载和执行 对于宏任务,JavaScript 引擎会将其添加到任务队列(task queue)中,在当前任务
generator 是怎么做到中断和恢复的?
Posted on:2024年7月19日 at 10:37Generator 是一种特殊的函数类型,可以在函数执行过程中暂停和恢复执行。它通过使用 yield 表达式来实现中断和恢复执行的功能。 当 Generator 函数被调用时,它并不会立即执行,而是返回一个迭代器对象。每次调用迭代器对象的 next() 方法时,Generator 函数会从上一次执行的位置继续执行,直到遇到下一个 yield 表达式或函数结束。此时,Generator 函数将返回一
说说下面代码的输出结果
Posted on:2024年7月19日 at 10:33Promise.resolve().then(() => { console.log(0) return Promise.resolve(4) }).then((res) => { console.log(res) }) Promise.resolve().then(() => { console.log(1) }).then(() => { console.log(2) }).then(() =
canvas 和 webgl 有什么区别?
Posted on:2024年7月19日 at 10:32Canvas和WebGL都是用于在Web浏览器中绘制图形和动画的技术,但它们在实现和功能上有一些区别: 渲染方式: Canvas:Canvas使用2D渲染上下文(2D context)来绘制图形和图像。它基于像素的绘图系统,通过JavaScript脚本控制渲染过程。 WebGL:WebGL(Web Graphics Library)是基于OpenGL ES标准的JavaScript API,它可
说说下面代码的执行过程
Posted on:2024年7月19日 at 10:32var a=3; function c(){ alert(a); } (function(){ var a=4; c(); })(); 这段代码的执行过程如下: 定义变量 a 并赋值为 3。 定义一个函数 c,该函数弹出一个对话框显示变量 a 的值。 定义一个立即执行函数,并在其中定义变量 a 并赋值为 4。 在立即执行函数中调用函数 c。 函数 c 弹出一个对话框显示变量 a 的值,此时输出结果
说说下面代码的输出是什么?
Posted on:2024年7月19日 at 10:31function Foo(){ Foo.a = function(){ console.log(1); } this.a = function(){ console.log(2) } } Foo.prototype.a = function(){ console.log(3); } Foo.a = function(){ console.log(4); } Foo.a(); let obj = n
是否有使用过空值合并运算符(??),举几个可以使用的场景。
Posted on:2024年7月19日 at 10:29空值合并操作符(??) 是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。 与逻辑或操作符(||) 不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。 const foo = null ?? 'defau
addEventListener 第三个参数
Posted on:2024年7月19日 at 10:28addEventListener 语法 addEventListener(type, listener); addEventListener(type, listener, options); addEventListener(type, listener, useCapture); 参数type表示监听事件类型的大小写敏感的字符串。listener当所监听的事件类型触发时,会接收到一个事件通知(
改变this指向的方法有哪些?
Posted on:2024年7月19日 at 10:18有以下几种常用的方法可以改变this的指向: 使用bind()方法:bind()方法会创建一个新的函数,并将其内部的this绑定到指定的对象。例如: function sayHello() { console.log("Hello, " + this.name); } const person = { name: "John" }; const boundFunction = sayHello.b
数组中的reduce方法有用过吗,说说它的具体用途?
Posted on:2024年7月19日 at 09:23reduce()方法在JavaScript中是一个高阶函数,用于对数组中的每个元素进行累积操作,最终返回一个单一的值。 具体来说,reduce()方法接受两个参数:回调函数和可选的初始值。回调函数在每个数组元素上被调用,并且可以接受四个参数:累积值(上一次回调函数的返回值或初始值)、当前值、当前索引和原始数组。 reduce()方法的执行过程如下: 如果提供了初始值,则将其作为累积值(accumu
如果空数组调用reduce会发生什么?
Posted on:2024年7月19日 at 09:08当空数组调用reduce()方法时,如果没有提供初始值参数,则会抛出一个TypeError错误。这是因为在空数组上调用reduce()方法时,无法得到初始累积值。 例如: const emptyArray = []; const result = emptyArray.reduce((accumulator, currentValue) => accumulator + currentValue)
如何让 Proxy 去监听基本数据类型?
Posted on:2024年7月19日 at 08:52Proxy无法直接监听基本数据类型(如字符串、数字、布尔值等),因为它们是不可变的。Proxy只能在对象级别上进行操作,而不是基本数据类型。 当我们尝试使用Proxy包装基本数据类型时,会得到一个TypeError错误,因为基本数据类型不具有属性和方法。 以下展示了尝试在基本数据类型上应用Proxy时会发生的错误: const value = 'Hello'; const handler = {
描述下列代码的执行结果
Posted on:2024年7月19日 at 08:27foo(typeof a); function foo(p) { console.log(this); console.log(p); console.log(typeof b); let b = 0; } 在这段代码中,我们首先遇到了一个函数声明 foo,然后在 foo 函数内部,有三个语句: console.log(this);: 打印函数 foo 的执行上下文中的 this 值。由于 foo
MessageChannel 是什么,有什么使用场景?
Posted on:2024年7月19日 at 08:01MessageChannel 是一个 JavaScript API,用于在两个独立的执行环境(如 Web Workers 或者不同的 browsing contexts)之间建立双向通信的通道。MessageChannel 提供了两个通信端点(port1 和 port2),可以在两个不同的执行环境之间传递消息,并通过事件监听的方式来处理这些消息。 使用场景包括但不限于: Web Workers
怎么预防用户快速连续点击,造成数据多次提交?
Posted on:2024年1月3日 at 09:16为了防止重复提交,前端一般会在第一次提交的结果返回前,将提交按钮禁用。 实现的方法有很多种: css设置 pointer-events 为 none 增加变量控制,当变量满足条件时才执行点击事件的后续代码(比如给按钮的点击事件增加防抖) 如果按钮使用 button 标签实现,可以使用 disabled 属性 加遮罩层,比如一个全屏的loading,避免触发按钮的点击事件 ...
cookie 的有效时间设置为 0 会怎么样
Posted on:2023年9月10日 at 19:17Cookie过期时间设置为0,表示跟随系统默认,其销毁与Session销毁时间相同,会在浏览器关闭后删除。
怎么使用 Math.max、Math.min 获取数组中的最值?
Posted on:2023年5月19日 at 09:12Math.min()和Math.max()用法比较类似: console.log(Math.min(1, 5, 2, 7, 3)); // 输出:1 但它们不接受数组作为参数。 如果想使用数组作为参数,有以下两个方法: apply const arr = [1, 5, 2, 7, 3]; console.log(Math.min.apply(null, arr)); // 输出:1 扩展运算符 c
【Promise第21题】下面代码的输出是什么?
Posted on:2023年3月26日 at 08:41Promise.reject('err!!!') .then((res) => { console.log('success', res) }, (err) => { console.log('error', err) }).catch(err => { console.log('catch', err) }) 解析 .then函数中的两个参数。 第一个参数是用来处理Promise成功的函数,第二
给某个资源的链接,如 https://www.baidu.com/index.html ,请实现一个方法,获取该资源的后缀,如 html
Posted on:2023年3月12日 at 17:28本题主要考察字符串相关的方法,实现比较简单,下面列举两个实现方法。 var fileName = "https://www.baidu.com/index.html"; function getFileExtension(url){ if(typeof url !== 'string'){ return '' } // 方法一 return url.substring(url.lastIndexO
请对以下数组,根据 `born` 的值降序排列
Posted on:2023年3月3日 at 20:25const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name
编程实现温度转换,已知温度转换的关系式是:华氏度=32+摄氏度×1.8,现在要求输入摄氏度,输出对应的华氏度,小数保留两位
Posted on:2023年1月8日 at 20:48function convertTemperature(centigrade){ if(typeof centigrade !== 'number'){ throw new Error('Wrong parameter type!') } return (32 + centigrade * 1.8).toFixed(2) }
一个滚动公告组件,如何在鼠标滑入时停止播放,在鼠标离开时继续等待滑入时的剩余等待时间后播放?
Posted on:2022年10月12日 at 09:36轮播图的定时滚动,一般是使用 setInterval 实现。 可以监听轮播图的 mouseover 和 mouseout 事件,如果 mouseover 被触发,就清除定时轮播,并记录下一次轮播的剩余等待时间xs,如果 mouseout 被触发,就在 xs 的时间后立即进行切换,并且开启定时轮播。 当然其中的细节还比较多,比如 mouseover 的过程中手动切换了轮播图该怎么处理等等。
怎么把十进制的 0.2 转换成二进制?
Posted on:2022年10月9日 at 19:57进制转换是比较基础的,如果大家熟悉 js 的 API ,那么会首先想到这两个方法: 十进制转二进制:num.toString(2) 二进制转十进制:parseInt(num, 2) 所以答案就是 (0.2).toString(2),可以简写为 0.2.toString(2)
连续 bind()多次,输出的值是什么?
Posted on:2022年6月5日 at 20:43var bar = function(){ console.log(this.x); } var foo = { x:3 } var sed = { x:4 } var func = bar.bind(foo).bind(sed); func(); //? var fiv = { x:5 } var func = bar.bind(foo).bind(sed).bind(fiv); func();
将数组的length设置为0,取第一个元素会返回什么?
Posted on:2022年5月11日 at 22:38设置 length = 0 会清空数组,所以会返回 undefined
const声明了数组,还能push元素吗,为什么?
Posted on:2022年4月17日 at 20:26可以 数组是引用类型,const声明的引用类型变量,不可以变的是变量引用始终指向某个对象,不能指向其他对象,但是所指向的某个对象本身是可以变的
以下代码的输出是什么?
Posted on:2022年4月10日 at 15:01var name = 'window' const obj = { name: 'obj', sayName:function() { console.log(this.name) }, } obj.sayMyName = () => { console.log(this.name) } const fn1 = obj.sayName const fn2 = obj.sayMyName fn1()
给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,说下会执行几次事件,然后会先执行冒泡还是捕获?
Posted on:2022年4月10日 at 12:04addEventListener绑定几次就执行几次 先捕获,后冒泡
如何获取到一个实例对象的原型对象?
Posted on:2022年4月5日 at 17:28从 构造函数 获得 原型对象: 构造函数.prototype 从 对象实例 获得 父级原型对象: 方法一: 对象实例.__proto__ 【 有兼容性问题,不建议使用】 方法二:Object.getPrototypeOf( 对象实例 )
我现在有一个canvas,上面随机布着一些黑块,请实现方法,计算canvas上有多少个黑块。
Posted on:2022年3月8日 at 23:40这一题可以转化成图的联通分量问题。通过getImageData获得像素数组,从头到尾遍历一遍,就可以判断每个像素是否是黑色。同时,准备一个width * height大小的二维数组,这个数组的每个元素是1/0。如果是黑色,二维数组对应元素就置1;否则置0。 然后问题就被转换成了图的连通分量问题。可以通过深度优先遍历或者并查集来实现。
使用Promise封装一个异步加载图片的方法
Posted on:2022年1月9日 at 23:31这个比较简单,只需要在图片的onload函数中,使用resolve返回一下就可以了。 function loadImg(url) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = function() { resolve(img); }; img.onerror = function(
【Promise第39题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:24const async1 = async () => { console.log('async1'); setTimeout(() => { console.log('timer1') }, 2000) await new Promise(resolve => { console.log('promise1') }) console.log('async1 end') return 'async1
【Promise第37题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:24async function async1 () { try { await Promise.reject('error!!!') } catch(e) { console.log(e) } console.log('async1'); return Promise.resolve('async1 success') } async1().then(res => console.log(res))
【Promise第36题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:23async function async1 () { await async2(); console.log('async1'); return 'async1 success' } async function async2 () { return new Promise((resolve, reject) => { console.log('async2') reject('error') }
【Promise第35题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:23async function testSometing() { console.log("执行testSometing"); return "testSometing"; } async function testAsync() { console.log("执行testAsync"); return Promise.resolve("hello async"); } async function
【Promise第34题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:16async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } console.log("script start"); setTimeout(function(
【Promise第33题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:15async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1') resolve('promise resolve') }) console.log('async1 success'); return 'async1 end' } consol
【Promise第32题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:15async function async1 () { console.log('async1 start'); await new Promise(resolve => { console.log('promise1') }) console.log('async1 success'); return 'async1 end' } console.log('srcipt start') async
【Promise第31题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:15async function fn () { // return await 1234 // 等同于 return 123 } fn().then(res => console.log(res)) 解析 正常情况下,async中的await命令是一个Promise对象,返回该对象的结果。 但如果不是Promise对象的话,就会直接返回对应的值,相当于Promise.resolve() 结果 123
【Promise第30题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:15async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); setTimeout(() => { console.log('timer1') }, 0) } async function async2() { setTimeout(() => { console.
【Promise第29题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:15async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { setTimeout(() => { console.log('timer') }, 0) console.log("async2"); } asy
【Promise第27题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:14function runAsync(x) { const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000) ); return p; } function runReject(x) { const p = new Promise((res, rej) => setTimeout(() => rej(`Error:
【Promise第26题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:14function runAsync (x) { const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000)) return p } function runReject (x) { const p = new Promise((res, rej) => setTimeout(() => rej(`Error: ${
【Promise第25题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:02function runAsync (x) { const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000)) return p } Promise.all([runAsync(1), runAsync(2), runAsync(3)]) .then(res => console.log(res)) 解析 .all(
【Promise第22题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:02Promise.resolve() .then(function success (res) { throw new Error('error!!!') }, function fail1 (err) { console.log('fail1', err) }).catch(function fail2 (err) { console.log('fail2', err) }) 解析 由于Promi
【Promise第20题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log) 解析 .then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。 第一个then和第二个then中传入的都不是函数,一个是数字类型,一个是对象类型,因此发生了透传,将resolve(1) 的值直接传到最后一个then里。 结果 1
【Promise第19题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01const promise = Promise.resolve().then(() => { return promise; }) promise.catch(console.err) 解析 .then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环,因此结果会报错。 结果 Uncaught (in promise) TypeError: Chaining cycle d
【Promise第18题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01Promise.resolve().then(() => { return new Error('error!!!') }).then(res => { console.log("then: ", res) }).catch(err => { console.log("catch: ", err) }) 解析 返回任意一个非 promise 的值都会被包裹成 promise 对象,因此这里的ret
【Promise第17题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01const promise = new Promise((resolve, reject) => { setTimeout(() => { console.log('timer') resolve('success') }, 1000) }) const start = Date.now(); promise.then(res => { console.log(res, Date.now() -
【Promise第16题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01Promise.reject(1) .then(res => { console.log(res); return 2; }) .catch(err => { console.log(err); return 3 }) .then(res => { console.log(res); }); 解析 因为reject(1),此时走的是catch,且第二个then中的res得到的就是catch中的返回
【Promise第15题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01Promise.resolve(1) .then(res => { console.log(res); return 2; }) .catch(err => { return 3; }) .then(res => { console.log(res); }); 解析 Promise可以链式调用,不过promise 每次调用 .then 或者 .catch 都会返回一个新的 promise,从而实现
【Promise第14题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01const promise = new Promise((resolve, reject) => { reject("error"); resolve("success2"); }); promise .then(res => { console.log("then1: ", res); }).then(res => { console.log("then2: ", res); }).catch(
【Promise第13题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01const promise = new Promise((resolve, reject) => { resolve("success1"); reject("error"); resolve("success2"); }); promise .then(res => { console.log("then: ", res); }).catch(err => { console.log("catc
【Promise第12题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:01const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("success"); console.log("timer1"); }, 1000); console.log("promise1里的内容"); }); const promise2 = promise1.then(() => { thro
【Promise第七题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:00console.log('start') setTimeout(() => { console.log('time') }) Promise.resolve().then(() => { console.log('resolve') }) console.log('end') 解析 刚开始整个脚本作为一个宏任务来执行,对于同步代码直接压入执行栈进行执行,因此先打印出start和end。 setTi
【Promise第六题】下面代码的输出是什么?
Posted on:2022年1月9日 at 23:00const fn = () => new Promise((resolve, reject) => { console.log(1); resolve("success"); }); console.log("start"); fn().then(res => { console.log(res); }); 解析 start就在1之前打印出来了,因为fn函数是之后执行的。 注意:不要看到new P
【Promise第二题】下面代码的输出是什么?
Posted on:2022年1月9日 at 22:26const promise = new Promise((resolve, reject) => { console.log(1); resolve('success') console.log(2); }); promise.then(() => { console.log(3); }); console.log(4); 过程分析 从上至下,先遇到new Promise,执行其中的同步代码1 再
【Promise第五题】下面代码的输出是什么?
Posted on:2022年1月9日 at 22:24const fn = () => (new Promise((resolve, reject) => { console.log(1); resolve('success') })) fn().then(res => { console.log(res) }) console.log('start') 分析 fn函数直接返回了一个new Promise的,而且fn函数的调用是在start之前,所以
【Promise第三题】下面代码的输出是什么?
Posted on:2022年1月9日 at 22:20const promise = new Promise((resolve, reject) => { console.log(1); console.log(2); }); promise.then(() => { console.log(3); }); console.log(4); 过程分析 和【Promise第二题】相似,只不过在promise中并没有resolve或者reject 因此pr
【Promise第一题】下面代码的输出是什么?
Posted on:2022年1月9日 at 22:19const promise1 = new Promise((resolve, reject) => { console.log('promise1') }) console.log('1', promise1); 过程分析: 从上至下,先遇到new Promise,执行该构造函数中的代码promise1 然后执行同步代码1,此时promise1没有被resolve或者reject,因此状态还是pe
使用js生成1-10000的数组
Posted on:2021年12月26日 at 22:26实现的方法很多,除了使用循环(for,while,forEach等)外,最简单的是使用Array.from // 方法一 Array.from(new Array(10001).keys()).slice(1) // 方法二 Array.from({length:10000},(node,i)=> i+1)
js中的undefined和 ReferenceError: xxx is not defined 有什么区别?
Posted on:2021年12月26日 at 16:06ReferenceError:当尝试引用一个未定义的变量/函数时,就会抛出ReferenceError。 undefined:当一个变量声明后,没有被赋值,那么它就是undefined类型。
Math.ceil()、Math.round()、Math.floor()三者的区别是什么?
Posted on:2021年12月26日 at 16:06Math.ceil()上取整 Math.round() 四舍五入 Math.floor()下取整
解释下如下代码的意图:Array.prototype.slice.apply(arguments)
Posted on:2021年12月26日 at 16:05arguments 为类数组对象,并不是真正的数组。 slice可以实现数组的浅拷贝。 由于 arguments不是真正的数组,所以没有slice方法,通过apply可以调用数组对象的slice方法,从而将arguments 类数组转换为数组。
直接在script标签中写 export 为什么会报错?
Posted on:2021年12月26日 at 16:05现代浏览器可以支持用 script 标签引入模块或者脚本,如果要引入模块,必须给 script 标签添加 type=“module”。如果引入脚本,则不需要 type。
Math.ceil 和 Math.floor 有什么区别?
Posted on:2021年11月17日 at 22:50Math.ceil() : 向上取整,函数返回一个大于或等于给定数字的最小整数。 Math.floor() : 向下取整,函数返回一个小于或等于给定数字的最大整数。
mouseover 和 mouseenter 有什么区别?
Posted on:2021年11月17日 at 22:49当鼠标移动到元素上时就会触发 mouseenter 事件,类似 mouseover,它们两者之间的差别是 mouseenter 不会冒泡。 由于 mouseenter 不支持事件冒泡,导致在一个元素的子元素上进入或离开的时候会触发其 mouseover 和 mouseout 事件,但是却不会触发 mouseenter 和 mouseleave 事件。
toPrecision 和 toFixed 和 Math.round 有什么区别?
Posted on:2021年11月17日 at 22:48toPrecision 用于处理精度,精度是从左至右第一个不为 0 的数开始数起。 toFixed 是对小数点后指定位数取整,从小数点开始数起。 Math.round 是将一个数字四舍五入到一个整数。
什么是 Polyfill ?
Posted on:2021年11月17日 at 22:25Polyfill 指的是用于实现浏览器并不支持的原生 API 的代码。 比如说 querySelectorAll 是很多现代浏览器都支持的原生 Web API,但是有些古老的浏览器并不支持,那么假设有人写了一段代码来实现这个功能使这些浏览器也支持了这个功能,那么这就可以成为一个 Polyfill。
怎么检测浏览器版本?
Posted on:2021年11月17日 at 22:25检测浏览器版本一共有两种方式: 一种是检测 window.navigator.userAgent 的值,但这种方式很不可靠,因为 userAgent 可以被改写,并且早期的浏览器如 ie,会通过伪装自己的 userAgent 的值为 Mozilla 来躲过服务器的检测。 第二种方式是功能检测,根据每个浏览器独有的特性来进行判断,如 ie 下独有的 ActiveXObject。
如何判断当前脚本运行在浏览器还是 node 环境中?
Posted on:2021年11月17日 at 22:24this === window ? 'browser' : 'node'; 通过判断 Global 对象是否为 window,如果不为 window,当前脚本没有运行在浏览器中。
使用原生js给一个按钮绑定两个onclick事件
Posted on:2021年9月25日 at 19:05//事件监听 绑定多个事件 var btn = document.getElementById("btn"); btn.addEventListener("click",hello1); btn.addEventListener("click",hello2); function hello1(){ alert("hello 1"); } function hello2(){ alert("hel
typeof NaN 的结果是什么?
Posted on:2021年8月22日 at 18:38NaN 指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。 typeof NaN; // "number" NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN !==
Object.is() 与比较操作符 “===”、“==” 的区别?
Posted on:2021年8月22日 at 18:37使用双等号(==)进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。 使用三等号(===)进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false。 使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的。
Promise中的值穿透是什么?
Posted on:2021年8月15日 at 15:28解释:.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。 当then中传入的不是函数,则这个then返回的promise的data,将会保存上一个的promise.data。这就是发生值穿透的原因。而且每一个无效的then所返回的promise的状态都为resolved。 Promise.resolve(1) .then(2) // 注意这里 .then(Promise.
bind() 连续调用多次,this的绑定值是什么呢?
Posted on:2021年8月15日 at 15:28var bar = function(){ console.log(this.x); } var foo = { x:3 } var sed = { x:4 } var func = bar.bind(foo).bind(sed); func(); //? var fiv = { x:5 } var func = bar.bind(foo).bind(sed).bind(fiv); func();
WebSocket 中的心跳是为了解决什么问题?
Posted on:2021年7月11日 at 16:10为了定时发送消息,使连接不超时自动断线,避免后端设了超时时间自动断线。所以需要定时发送消息给后端,让后端服务器知道连接还在通消息不能断。 为了检测在正常连接的状态下,后端是否正常。如果我们发了一个定时检测给后端,后端按照约定要下发一个检测消息给前端,这样才是正常的。如果后端没有正常下发,就要根据设定的超时进行重连。
如何判断一个对象是不是空对象?
Posted on:2021年7月11日 at 16:10// 方法1 Object.keys(obj).length === 0 // 方法2 JSON.stringify(obj) === '{}'
NaN 是什么,用 typeof 会输出什么?
Posted on:2021年7月11日 at 16:10NaN:Not a Number,表示非数字 typeof NaN === 'number'
Babel 是什么?
Posted on:2021年7月11日 at 14:57Babel 是一个 JavaScript 编译器。 Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
npm 是什么?
Posted on:2021年7月11日 at 11:17npm是Node.js的包管理工具,它的诞生也极大的促进了前端的发展,在现代前端开发中都离不开npm的身影。 常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用。 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
什么是微前端?
Posted on:2021年7月11日 at 11:08微前端(Micro-Frontends)是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。 各个前端应用还可以独立运行、独立开发、独立部署。 微前端不是单纯的前端框架或者工具,而是一套架构体系,
[] == ![]结果是什么?
Posted on:2021年7月7日 at 00:15== 中,左右两边都需要转换为数字然后进行比较。 []转换为数字为0。 ![] 首先是转换为布尔值,由于[]作为一个引用类型转换为布尔值为true, 因此![]为false,进而在转换成数字,变为0。 0 == 0 , 结果为true
forEach中return有效果吗?如何中断forEach循环?
Posted on:2021年7月7日 at 00:14在forEach中用return不会返回,函数会继续执行。 中断方法 使用try监视代码块,在需要中断的地方抛出异常。 官方推荐方法(替换方法):用every和some替代forEach函数。 every在碰到return false的时候,中止循环。 some在碰到return true的时候,中止循环。
下面执行后输出什么?
Posted on:2021年7月7日 at 00:14for(var i = 1; i <= 5; i ++){ setTimeout(function timer(){ console.log(i) }, 0) } 结论: 输出5个6。 因为setTimeout为宏任务,由于JS中单线程eventLoop机制,在主线程同步任务执行完后才去执行宏任 务,因此循环结束后setTimeout中的回调才依次执行,但输出i的时候当前作用域没有,往上一级再找,
instanceof能否判断基本数据类型?
Posted on:2021年7月7日 at 00:14能。比如下面这种方式: class PrimitiveNumber { static [Symbol.hasInstance](x) { return typeof x === 'number' } } console.log(111 instanceof PrimitiveNumber) // true 其实就是自定义instanceof行为的一种方式,这里将原有的instanceof方法重定义
什么是BigInt?
Posted on:2021年7月7日 at 00:14BigInt是一种新的数据类型,用于当整数值大于Number数据类型支持的范围时。这种数据类型允许我们安全地对 大整数 执行算术操作,表示高分辨率的时间戳,使用大整数id,等等,而不需要使用库。
0.1+0.2为什么不等于0.3?
Posted on:2021年7月7日 at 00:140.1和0.2在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成 0.30000000000000004。
null是对象吗?为什么?
Posted on:2021年7月7日 at 00:14null不是对象。 虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 。
webSocket如何兼容低浏览器
Posted on:2021年7月4日 at 16:07Adobe Flash Socket; ActiveX HTMLFile (IE) ; 基于 multipart 编码发送 XHR; 基于长轮询的 XHR;