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

news2024/7/6 19:24:11

72.get 请求传参长度的误区

常说:get 请求参数的大小存在限制,而 post 请求的参数大小无限制。 实际上 HTTP 协议并未规定 get / post 的请求参数大小限制。

纠正误区:是浏览器或 web 服务器对 get 请求参数的最大长度显示进行限制(即限制 url 的长度)并且,不同的浏览器和 WEB 服务器,限制的最大长度不一样:若考虑支持IE,最大长度为 2083byte;若只支持 Chrome,最大长度为 8182byte。

73.get 和 post 的区别

参考链接:GET 和 POST 的区别? - 知乎

GET和POST请求的区别(超详细)post和get的区别Shao_Taylor的博客-CSDN博客

HTTP 常见请求方式:GET、POST、PUT、DELETE

HTTP协议是基于TCP/IP的应用层协议, GET和``POST都使用同一个传输层协议,所以在传输上没区别

1.缓存方面:

get 类似于查找的过程,用户获取数据不需要每次都与数据库连接,因此可以使用缓存。

post 主要进行修改和删除,必须与数据库交互,因此不能使用缓存。

2. 报文格式:

get 方法的参数放在 url 中,post 方法的参数放在 body 中

3.安全性:

从传输的角度来说,由于HTTP自身是一个明文协议,每个HTTP请求和返回的数据在网络上都是明文传输 (包括 urlheader和 ``body)。 在网络节点抓包就能获取完整的数据报文,要防止泄密的唯一手段就是使用HTTPS(用SSL协议协商出的密钥加密明文HTTP数据)。这里要注意,post 可以进行复杂的加密,get 不可以。

但相对来说,get请求参数会以 url 的形式保留在浏览器的记录里,存在安全问题。

post 数据放在请求主体body中,数据不会被浏览器记录。

因此,get 方法对于服务器更安全,post 方法对于客户端更安全。

4.长度及参数类型限制:

在浏览器中,对GET请求方式的url长度有限制,对post没有。

因为浏览器要对url进行解析,解析时要分配内存。对于一个字节流的解析,必须分配buffer来保存所有要存储的数据。而url必须当作一个整体,无法分块处理,因此处理一个 get 请求时必须分配一整块足够大的内存。如果url太长,并发又很高,就容易超出服务器的内存。

get 只支持 ASCII 字符格式的参数, post 方法没有限制。

5.数据包的发送:

post方法有时会发送两个 tcp 数据包(先发送 Header 再发送 Data),与浏览器有关(火狐)。

GET 方法 Header 和 Data 一起发送。

6.幂等性:

get 方法具有幂等性,post 方法不具有

幂等性:同样的请求被执行一次与连续执行多次的效果一样,服务器状态也一样

74.类的创建和继承

(1).类的创建:

new 一个 function,在这个 function 的 prototype 中增加属性和方法。

创建一个 Animal 类:

// 定义一个动物类
function Animal (name) {
    // 属性
    this.name = name || 'Animal';
    // 实例方法
    this.sleep = function(){
        console.log(this.name + '正在睡觉!');
    }
}
// 原型方法
Animal.prototype.eat = function(food) {
    console.log(this.name + '正在吃:' + food);
};

生成一个 Animal 类,实例化生成对象后,有方法和属性。

(2).类的继承——原型链继承

特点:基于原型链,既是父类的实例,也是子类的实例

缺点:无法实现多继承

在下面的代码中:

new 一个空对象,这个空对象指向 Animal,Cat.prototype 指向这个空对象,这就是基于原型链的继承。

// 定义一个具体的 Cat 类
// new 一个空对象,这个空对象指向 Animal
function Cat() {};
​
// Cat.prototype 指向了这个空对象
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
​
var cat = new Cat();
​
// 进行输出测试
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true

(3).构造继承

使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类

注:这里不涉及原型

特点:可以实现多继承

缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法。

function Cat(name){
    Animal.call(this);
    this.name = name || 'Tom';
}
​
var cat = new Cat();
​
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

(4).实例继承和拷贝继承

实例继承:为父类实例添加新特性,作为子类实例返回

拷贝继承:拷贝父类元素上的属性和方法

(5).组合继承

相当于构造继承和原型链继承的组合体。通过调用父类构造函数,继承父类的属性并保留传参的优点,再通过将父类实例作为子类原型,实现函数复用

特点:可以继承实例属性/方法,也可以继承原型属性/方法

缺点:调用了两次父类构造函数,生成两份实例

function Cat(name){
    Animal.call(this);
    this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
​
var cat = new Cat();
​
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

(6).寄生组合继承:

通过寄生方式,砍掉父类的实例属性,在调用两次父类的构造时,不会初始化两次实例方法/属性

75.如何让事件先冒泡后捕获

在 DOM 标准事件模型中,先捕获后冒泡。

如果要实现先冒泡后捕获,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后,再执行捕获事件。

76.事件委托

事件委托指,不在事件发生的dom元素上设置监听函数,而是在其父元素上设置,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素 DOM 的类型,来做出不同的响应。

举例:ul 和 li 标签的事件监听,在添加事件时采用事件委托机制,不在 li 标签上添加,而是在 ul 元素上添加。

优点:适合动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。

77.图片的懒加载和预加载

预加载:提前加载图片,当用户需要查看时,可直接从本地缓存中渲染。

懒加载:主要目的是服务器前端的优化,减少请求数或延迟请求数。

两种技术的本质:两者行为相反,一个是提前加载,一个是迟缓甚至不加载。

懒加载对服务器前端有一定的缓解压力作用,预加载会增加服务器前端压力。

78.mouseover 和 mouseenter 的区别

mouseover:当鼠标移入元素或其子元素都会触发事件,有冒泡的过程。对应移除事件: mouseout

mouseenter:当鼠标移入元素本身会触发事件,不会冒泡。对应移除事件: mouseleave

79.clientHeight, scrollHeight, offsetHeight 以及 scrollTop, offsetTop, clientTop 的区别

clientHeight:可视区域的高度,不包含 border 和滚动条

offsetHeight:可视区域的高度,包含 border 和滚动条

scrollHeight:所有区域的高度,包含因滚动被隐藏的部分

offsetParent:距离元素最近的一个具有定位的祖宗元素,若都没有定位,则为 body

clientTop:边框 border 的厚度,未指定情况下一般为 0

offsetHeight:元素到 offsetParent 顶部的距离

scrollTop:滚动后被隐藏的高度,获取对象相对于由 offsetParent 属性指定的父坐标(css

定位的元素或 body 元素)距离顶端的高度。

imgimg

注:只有元素渲染完成才会计算入 offsetTop,若中间有元素数据需异步获取,则 offsetTop 值最终偏小。

80.Ajax 解决浏览器缓存问题

在 ajax 发送请求前加 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。

在 ajax 发送请求前加 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。

在 URL 后面加一个随机数: "fresh=" + Math.random()。

在 URL 后面加时间戳:"nowtime=" + new Date().getTime()。

如果是使用 jQuery:$.ajaxSetup({cache:false}),这样页面的所有 ajax 都会执行这条语句,不需要保存缓存记录。

81.eval 是做什么的

将对应的字符串解析成 JS 并执行,应避免使用 JS,消耗性能(2 次,一次解析成 JS,一次执行)

82.对象深度克隆的简单实现

function deepClone(obj) {
    var newObj= obj instanceof Array ? [] : {};
    for(var item in obj) {
        // 数组是对象,但与对象有一定区别
        var temple = typeof obj[item] == 'object' ? deepClone(obj[item]) : obj[item];
        newObj[item] = temple;
    }
    return newObj;
}

83.实现一个 once 函数,传入函数参数只执行一次

function ones(func) {
    var tag = true;
    return function() {
        if(tag) {
            func.apply(null, arguments);
            tag = false;
        }
    return undefined;
    }
}

84.将原生的 ajax 封装成 promise

var myAjax = (url) => {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', url);
        xhr.send(data);
        xhr.onreadystatechange = function() {
            if(xhr.readyState == 4 && xhr.status == 200 ){
                var json = JSON.parse(xhr.responseText);
                resolve(json);
            }
            else if(xhr.readyState == 4 && xhr.status != 200) {
                reject('error');
            }
        }
    })
}

85.JS 监听对象属性的改变

假设一个 user 对象

(1) 在 ES5 中,可以通过 Object.defineProperty 来监听已有属性

Object.defineProperty(user, 'name', {
    set:function(key,value) {
    }
})

缺点:如果 id 不在 user 对象中,则不能监听 id 的变化

(2) 在 ES6 中,可以通过 Proxy 来实现

即使属性在 user 中不存在,通过 user.id 来定义也可以监听属性

var user = new Proxy({}, {
    set:function(target, key, value, receiver) {
    }
})

86.如何实现一个私有变量,用 getName 方法可以访问,但不能直接访问

(1) 通过 defineProperty 实现

obj = {
    name: yuxiaoliang,
    getName: function() {
        return this.name
    }
}
object.defineProperty(obj, "name", {
    //不可枚举 不可配置
});

(2) 通过函数的创建形式

function product() {
    var name = 'xiaoZhao';
    this.getName = function() {
        return name;
    }
}
var obj = new product();

87.setTimeout、setInterval 和 requestAnimationFrame(RAF)之间的区别

参考链接:深入理解定时器系列第二篇——被誉为神器的requestAnimationFrame - 小火柴的蓝色理想 - 博客园

RAF 不需要设置时间间隔,采用的是系统时间间隔,不会因为间隔时间的长短而受影响。

如果前面的任务多,会影响 setTimeout 和 setInterval 真正运行时的时间间隔。 setTimeout 和 setInterval 不精确,它们的内在运行机制决定了时间间隔参数。实际上只是指定了 把动画代码添加到浏览器UI线程队列中 等待执行的时间。如果队列前面加入了其他任务,那动画代码要等前面的任务完成后再执行。

特点:

(1)RAF 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中完成,并且重绘或回流的时间间隔取决于浏览器的刷新频率。

(2)在不可见的元素中,RAF 将不会进行重绘或回流,因此CPU、GPU 和内存使用量更少

(3)RAF 是由浏览器专门为动画提供的 API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了 CPU 开销。

88.实现一个 bind 函数

原理:通过 apply 或者 call 方法来实现。

(1)初始版本

Function.prototype.bind = (obj,arg) => {
    var arg = Array.prototype.slice.call(arguments, 1);
    var context = this;
    return (newArg) => {
        arg = arg.concat(Array.prototype.slice.call(newArg));
        return context.apply(obj, arg);
    }
}

(2) 考虑原型链

在 new 一个 bind 生成的新函数的时候,必须的条件是要继承原函数的原型

Function.prototype.bind = (obj, arg) => {
    var arg = Array.prototype.slice.call(arguments, 1);
    var context = this;
    var bound = (newArg) => {
        arg = arg.concat(Array.prototype.slice.call(newArg));
        return context.apply(obj,arg);
    }
    var F = () => {}
    // 这里需要一个寄生组合继承
    F.prototype = context.prototype;
    bound.prototype = new F();
    return bound;
}

89.用 setTimeout 实现 setInterval

用 setTimeout() 方法来实现 setInterval() 与 setInterval()自身 之间的区别:

使用 setInterval() 创建的定时器确保了定时器代码规则地插入队列中。这个问题在于:如果定时器代码 在代码再次添加到队列之前 还没完成执行,就会导致定时器代码连续运行多次, 并且之间没有间隔。但是 javascript 能避免这个问题。当且仅当没有该定时器的代码实例时,才会将定时器代码添加到队列中。确保了定时器代码加入队列中最小的时间间隔为指定时间。

重复定时器的规则有两个问题:1.某些间隔被跳过 2.多个定时器的代码执行时间可能比预期小

img

如上图例子中,第一个定时器是在 205ms 处添加到队列中,但是要过 300ms 才能执行。在405ms 又添加了一个副本。在 605ms 处,第一个定时器代码还在执行中,而且队列中已经有一个定时器实例,所以 605ms 的定时器代码不会添加到队列中。在 5ms 处添加的定时器代码执行结束后,405 处的代码立即执行。

function say() {
    // some codes
    setTimeout(say, 200);
}
setTimeout(say, 200);
​
OR
​
setTimeout(function() {
    // some codes
    setTimeout(arguments.callee, 200);
}, 200);

90.代码的执行顺序

这道题的衍生在多个大厂的笔试题中出现

参考文章:从promise、process.nextTick、setTimeout出发,谈谈Event Loop中的Job queue · Issue #5 · forthealllight/blog · GitHub

setTimeout(function() {
    console.log(1);
}, 0);
new Promise(function(resolve, reject) {
    console.log(2);
    resolve();
}).then(function() {
    console.log(3);
}).then(function() {
    console.log(4);
});
process.nextTick(function() {
    console.log(5)
});
console.log(6);
// 输出 2,6,5,3,4,1

分析:

首先执行主线程中的同步任务,主线程任务执行完毕后,再从 event loop(事件循环)中读取任务。

script (主程序代码) ——> process.nextTick ——> promise ——> setTimeout

I) 主体部分: 定义promise的构造部分是同步的,先输出2 ,再输出6

(同步情况下,严格按照定义的先后顺序)

II)) process.nextTick:输出5

III) promise:这里其实是promise.then部分,输出3,4

IV) setTimeout : 最后输出1

setTimeout(function() {
    console.log(1);
}, 0);
​
new Promise(function(resolve, reject) {
   console.log(2);
   setTimeout(function() {
    resolve();
}, 0)
}).then(function() {
    console.log(3);
}).then(function() {
    console.log(4)
});
​
process.nextTick(function() {
    console.log(5)
});
console.log(6);
​
//输出 2 6 5 1 3 4

分析:

和上面的区别在于promise的构造中,没有同步的resolve,因此promise.then在当前的执行队列中是不存在的,只有promise从pending转移到resolve,才会有then方法,而这个resolve是在一个setTimout时间中完成的,因此最后输出3, 4。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/467026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nature Neuroscience:高家红团队首次发布中国人脑连接组计划研究成果及其大数据资源

人类生活在充满多样性的世界里。长久以来的研究发现,人类的脑与行为受到基因、环境和文化及其相互作用的塑造,然而这种影响发生的机制始终缺乏系统性探索与研究。近年来,前沿神经影像技术方法飞速进步,推动着多模态脑成像大数据集…

索尼ILCE-7SM3覆盖恢复案例

ILCE-7SM3算是索尼的流量级产品了,目前使用的比较多。今天我们来看一个格式化后又覆盖的恢复案例,看看这种情况下如何恢复残留的视频素材。 故障文件:80G SD卡 故障现象: 80G卡实际容量在74.5G左右,ExFat文件系统,格式化后又录…

Java8新特性-Stream

文章目录 简介Stream 的特性创建Stream通过集合创建流通过数组创建流通过Stream.of方法创建流创建规律的无限流创建无限流创建空流 Stream操作分类中间操作无状态filtermapflapMap 有状态distinctsortedreversedthenComparinglimitskipconcat 终结操作非短路操作forEachreducec…

D. Kilani and the Game(BFS模拟向四周漫延的过程)

Problem - D - Codeforces Kilani正在和他的朋友玩一个游戏。这个游戏可以表示为一个nm的网格,其中每个单元格都是空的或者被阻塞的,并且每个玩家在一些单元格中拥有一个或多个城堡(一个单元格中没有两个城堡)。 游戏分轮进行。每…

JS高级 -- 构造函数、数据常用函数

1. 深入对象 1.1 创建对象三种方式 利用对象字面量创建对象 const o {name:佩奇 }利用 new object 创建对象 const o new Object({ name:佩奇}) console.log(o) // {name: 佩奇}利用构造函数创建对象 1.2 构造函数 构造函数:是一种特殊的函数,主要…

SpringBoot+Vue3实现登录验证码功能

系列文章目录 Redis缓存穿透、击穿、雪崩问题及解决方法Spring Cache的使用–快速上手篇分页查询–Java项目实战篇全局异常处理–Java实战项目篇 Java实现发送邮件(定时自动发送邮件)_java邮件通知_心态还需努力呀的博客-CSDN博客 该系列文章持续更新…

最高效的七个云原生开发原则

​Cloud native是一种软件开发方法,利用云基础架构实现更快、更可扩展的部署。云原生应用程序旨在充分利用现代化的工程实践,如自动化、托管服务和自动扩展控制。 这种模式对组织文化和工作实践也有影响。云技术应成为软件交付的重要组成部分。每个人都…

迅为三星4412开发板UDP实现服务器和客户端

UDP 协议是开放式,无连接,不可靠的传输层通信协议,但它收发数据的速度相对于 TCP 快很多,常 用在传输音视频等数据量非常大的场合。 udp 网络编程只需要使用一个类 QUdpSocket。 本实验中对 QUdpSocket 的基本使用: …

选择DAO的组织结构时,应着重考虑的各个关键阶段与安全可靠性

近年来,去中心化自治组织 (Decentralized Autonomous Organizations,DAO)已成为了管理智能合约项目和社区的流行方式。简单而言,DAO是一个基于智能合约运作的数字化组织。组织内的成员可以根据对应的模型结构,做出不同的决策。虽然…

哪款蓝牙耳机学生用合适?学生党平价无线耳机推荐

近年来,蓝牙耳机凭借使用便捷,成为了许多人生活中不可或缺的一部分。不管是听歌、追剧还是玩游戏,或者运动等等,都能看到戴蓝牙耳机的人。那么,哪款蓝牙耳机适合学生用?下面,我来给大家推荐几款…

Unsupervised Learning of Depth and Ego-Motion from Video 论文精读

视频中深度和自我运动的无监督学习 摘要 我们提出了一个无监督学习框架,用于从非结构化视频序列中进行单眼深度和相机运动估计。与其他工作[10,14,16]一样,我们使用端到端的学习方法,将视图合成作为监督信号。与之前…

C++ 线程

linux使用线程 在linux使用线程可能出现,在编译时不会报错,但执行出错的问题。 undefined reference to pthread_create这是由于ubuntu平台下调用pthread_create()函数,pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 …

Word转PDF:简单步骤,轻松完成!推荐两个实现的方法

随着社会的发展,PDF 文件已经成为一种非常流行的文件格式,对于一些需要对文件进行保密的企业而言,更是必不可少。在这样的大背景下,如何将 Word 文件转换为 PDF 文件呢?下面是一些简单的步骤,帮助您轻松完成…

Rust-Shyper:基于 Rust 语言的高可靠、开源嵌入式 Hypervisor

「Rust-Shyper 是北京航空航天大学计算机学院王雷教授团队设计开发的虚拟机监控器,该系统基于 Rust 语言,实现了一个高可靠、嵌入式 Hypervisor。2023 年 2 月 15 日 Rust-Shyper 正式在 openEuler 社区开源。」 项目地址:https://gitee.com…

论文阅读笔记:Hearing Lips Improving Lip Reading by Distilling Speech Recognizers

目录 论文链接 研究背景 LIBS 的整体框架 序列级知识蒸馏 上下文级知识蒸馏 最长公共子序列 (LCS) 帧级别知识蒸馏 论文链接 [1911.11502] Hearing Lips: Improving Lip Reading by Distilling Speech Recognizers (arxiv.org) 研究背景 这篇文章针对由于唇语识别动作…

【观察】解码“一网统管”:城市治理“新范式”,推动数字城市建设迈向“新高度”...

众所周知,随着城市化进程加快,大量的人员、物资、技术和信息等要素日益向城市汇聚,城市系统变得越来越复杂,随之而来的社会问题和“城市病”也层出不穷,而传统的治理模式和治理手段越来越难以胜任日益复杂城市的管理需…

深聊丨第四范式陈雨强:如何用AI大模型打开万亿规模传统软件市场?

文丨亲爱的数据 谭婧 “GPT大模型到底能不能用?用在哪里?” 这是目前中国大型企业一把手最关心的问题之一。AI大模型也被媒体称为“一把手”工程。 大型企业会非常认真地考虑大模型的应用。最近个把月,大型企业客户对大模型的热烈反应让第四范…

进程状态以及两种特殊进程

目录 进程状态1 具体状态2 进程状态的意义3 进程状态实例3.1 R&S&T认识3.2 认识Z & 僵尸进程 & 孤儿进程僵尸进程孤儿进程 进程状态 为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内…

==、equals区别 | java学习笔记

做一些java基础知识的记录📕 java基本类型:byte short int long float double char boolean(指向具体的数值) java引用类型:类 接口 数组等。指向的不是具体的数值,而是指向了对象的地址。 用于判断基本类…

JavaWeb|在IDEA中创建基于Maven的Web项目| Servlet依赖|这一篇就够了(超详细)

🙈作者简介:练习时长两年半的Java up主 🙉个人主页:老茶icon 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,计…