本篇译文,删减了原文中一些无关紧要的内容,可以让大家花更少的阅读时间。 原文地址:https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec
这篇文章将讨论日常编程中另一个复杂且容易被忽视的问题 — 内存管理。其中还提供了一些关于如何处理 JavaScript 内存泄露的提示,来防止导致内存泄漏以及不会增加我们 WEB 程序的内存消耗。
Overview
像 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()
和 free()
。相反,JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。 释放的过程称为垃圾回收。这个“自动”是混乱的根源,并让 JavaScript(和其他高级语言)开发者错误的感觉他们可以不关心内存管理。
即使使用高级开发语言,开发人员也应该了解内存管理(或至少了解其基础知识)。有时自动内存管理会存在一些问题(如垃圾回收的 bug 和实现限制等)。开发者必须了解相关内存知识才能解决(或找到合适的解决方法,并尽量减少折衷和代码债务)来处理这些问题。
Memory life cycle
无论使用何种编程语言,内存生命周期几乎都是一样的: 以下概述了周期的每个步骤:
Allocate memory — 分配你所需要的内存。程序使用的内存由操作系统分配,在底层语言中(如C语言)这是开发人员需要处理的,在高级语言中由程序自动处理。
Use memory — 使用分配到的内存(读、写)。代码中使用变量对内存进行读、写 操作。
Release memory — 不需要时将其释放/归还。和 Allocate memory 一样,在底层语言中需要开发者自行明确的处理。
What is memory?
讨论 JavaScript 内存之前,我们先简单地讨论一下内存是什么以及它是如何工作的?
在硬件级别上,计算机内存包含大量触发器(flip flops)。每个触发器包含几个晶体管并且能够存储一位(bit)。单个触发器可通过唯一标识符进行寻址,因此我们可以读取和覆盖它们。从概念上讲,我们可以将整个计算机内存视为我们可以读写的一个巨大的位(bit)数组。
因为人类,不善于做一些 bits 的运算和思考,所以将其组织成更大的组来表示数值。8 bits 为 1 byte,超出 byte的,有单词(16bits 或 32bits)
大量的东西存储在内存中,包括:
程序中使用的所有变量以及其他数据
程序代码,以及包括操作系统的代码
虽然编译器和操作系统已经为内存管理做了大量工作,但是还是建议了解一下引擎之下发生了什么。
编译代码时,编译器可以检查原始数据类型,并提前计算它们所需内存。然后将所需的数量分配给调用堆栈中的程序。这些变量分配的空间称为堆栈空间(stack space ),因为函数被调用,它们的内存被添加到现有内存(存储器)的顶部。它们终止时,它们将以LIFO(后进先出)顺序被移除。
int n;
int x[ 4 ] ;
double m;
编译器可以立即计算diam所有内存空间为: 4 + 4 × 4 + 8 = 28 b y t e s 4 + 4 × 4 + 8 = 28 bytes 4 + 4 × 4 + 8 = 2 8 b y t e s
这是现在整数和双精度的工作原理。大约 20 年前,整数通常为 2 字节,双精度为 4 字节。你的代码永远不必依赖于此时基本数据类型的大小。
编译器将插入与操作系统交互的代码,以便在堆栈中请求要存储的变量所需的字节数。
上述示例中,编译器知道每个变量的确切内存地址。实际上,每当我们写入变量时,它就会会内部转为类似”内存地址 4127963“的内容。
注意,如果尝试访问x[4]
,可能会访问到和 m 相关联的数据。这是因为我们访问的元素在数组中并不存在 — 它比数组中最后一个实际分配的元素x[3]
多4个字节,可能会读取(或重写) m 的位。这肯定会对程序产生难以理解的不良影响。 当函数调用其他函数时,每个函数在调用时都会获得自己的堆栈块。它保存所有的局部变量,还有一个程序计数器,可以记录函数的执行位置。当函数执行完成时,其内存块可以再次用于其他目的。
Dynamic allocation
不幸的是,当在编译时不知道变量需要多少内存时,事情就不那么容易了。假设我们想要做类似以下的事情:
int n = readInput ( ) ;
...
这种情况下,在编译时,编译器不知道数组需要多少内存空间,因为其由用户输入的值来确定。
因此,它无法为堆栈上的变量分配空间。相反,我们的程序需要再运行时明确询问操作系统是否有适当的空间。此内存是从堆空间(heap space) 分配的。下述为静态分配和动态分配的差异:
Static allocation
Dynamic allocation
编译时内存大小确定
编译时内存大小不确定
编译阶段执行
运行时执行
分配给栈(stack space)
分配给堆(heap stack)
FILO
没有特定的顺序
Allocation in JavaScript
现在我们将解释第一步(分配内存 — Allocate memory)如何在JavaScript中工作。 JavaScript 使开发人员免于处理内存 — 其在声明时自动完成。
var n = 374 ;
var s = 'sessionstack' ;
var o = {
a: 1 ,
b: null
} ;
var a = [ 1 , null , 'str' ] ;
function f ( a) {
return a + 3 ;
}
someElement. addEventListener ( 'click' , function ( ) {
someElement. style. backgroundColor = 'blue' ;
} , false ) ;
一些函数调用也会导致对象分配:
var d = new Date ( ) ;
var e = document. createElement ( 'div' ) ;
方法可以分配新的值或对象:
var s1 = 'sessionstack' ;
var s2 = s1. substr ( 0 , 3 ) ;
var a1 = [ 'str1' , 'str2' ] ;
var a2 = [ 'str3' , 'str4' ] ;
var a3 = a1. concat ( a2) ;
Using memory in JavaScript
通常在JavaScript中使用内存的过程实际上是对分配内存进行读取与写入的操作。读取与写入可能是写入一个变量或者一个对象的属性值,甚至传递函数的参数。
Release when the memory is not needed anymore
大多数内存管理的问题都在这个阶段。在这里最艰难的任务是找到“哪些被分配的内存确实已经不再需要了”。它往往要求开发人员来确定在程序中哪一块内存不再需要并且释放它。
高级语言解释器嵌入了“垃圾回收器”,它的主要工作是跟踪内存的分配和使用,以便当分配的内存不再使用时,自动释放它。不幸的是,这只能是一个近似的过程,因为要知道是否仍然需要某块内存是无法判定的(无法通过某种算法解决)。
大多数垃圾回收器通过判断内存是否能够被再次访问来工作的,例如:指向它的所有变量都超出了作用域。然而,这只能得到一个近似值。因为在任何一点上,内存位置可能仍然有一个在作用域内指向它的变量,但是它可能将永远不会被再次访问了。
Garbage collection
自动寻找是否一些内存“不再需要”的问题是无法判定的。因此,垃圾回收实现只能有限制的解决一般问题。本节将解释必要的概念,了解主要的垃圾回收算法和它们的局限性。
Memory references
垃圾回收算法依靠的主要概念就是引用(reference) 。 在内存管理的环境中,一个对象如果有访问另一个对象的权限(隐式或者显式),叫做一个对象引用另一个对象。例如,一个Javascript对象具有对它原型的引用(隐式引用)和对它属性的引用(显式引用)。 在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。
词法作用域定义了如何在嵌套函数中解析变量名称:即使父函数已 return,内部函数也可以包含父函数的作用域。
引用计数垃圾收集 Reference-counting garbage collection
这是最初级的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
下述例子,使用了MDN中的例子,而并没有用原文中,因为发现了作者这部分内容完全来自 MDN o(╥﹏╥)o — https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management
var o = {
a: {
b: 2
}
} ;
var o2 = o;
o = 1 ;
var oa = o2. a;
o2 = "yo" ;
oa = null ;
Cycles are creating problems
该算法有个限制:无法处理循环引用的事例。在下面的例子中,两个对象被创建,并互相引用,形成了一个循环。它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。
function f ( ) {
var o1 = { } ;
var o2 = { } ;
o1. p = o2;
o2. p = o1;
}
f ( ) ;
标记-清楚算法 Mark-and-sweep algorithm
这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。 标记和扫描算法通过以下3个步骤:
根:一般来说,根是在代码中引用的全局变量。例如,在 JavaScript 中,可以充当根的全局变量是“window”对象。Node.js 中的相同对象称为“global”。垃圾收集器构建了所有根的完整列表。;
然后算法检查所有根和它们的孩子并将它们标记为 Active(意思是,它们不是垃圾)。root无法访问的任何内容都将被标记为垃圾。
最后,垃圾收集器释放所有未标记为 Active 的内存块,并将该内存返回给操作系统。
该算法优于“引用计数”算法,因为“一个对象具有零个引用”导致对象不能访问。这与上面循环应用相反。
截止到2012年,所有现代浏览器都提供了标记 - 清除垃圾收集器。在过去几年中,在 JavaScript 垃圾收集(生成/增量/并发/并行垃圾收集)领域所做的所有改进都是该算法的实现改进(mark-and-sweep),但不是对垃圾收集算法本身的改进,也不是决定对象是否可访问的目标。
Cycles are not a problem anymore
在上面的示例中,函数调用返回之后,两个对象从全局对象出发无法获取。因此,他们将会被垃圾回收器回收。 尽管对象之间存在引用,但它们无法从根目录(window)访问。
Counter intuitive behavior of Garbage Collectors
虽然垃圾收集器很方便,但它们还是有自己的权衡取舍。其中之一是非决定论(non-determinism)。换句话说,GC 是不可预测的,无法确定何时会执行收集。这意味着在某些情况下,程序使用的内存要比实际需要的还多。另一个场景是,在特别敏感的应用中,那么一些短暂的暂停会显得特别明显。虽然不确定性意味着回收执行的时间不能被确定,但是大多数 GC 的实现是共享模式 — 在分配内存期间执行回收遍历。如果没有分配执行,大多数 GCs 保持空闲状态。请考虑以下情形:
相当大的一组分配被执行
都被标记为无法访问(假设我们将指向我们不再需要的缓存的引用置空)
没有进一步的分配
在这种情况下,大多数GC不会再运行任何收集动作(passes)。换句话说,即使存在对于收集来说,无法访问的引用,收集器也不会声明这些引用(these are not claimed by the collector)。这些并非严格内存泄漏,但仍导致高于平常的内存使用率。
What are memory leaks?
内存泄漏是应用程序过去使用但后续不再需要,尚未返回操作系统或可用内存池的内存块。 编程语言支持不同的内存管理方式。但是,是否使用某段内存实际上是一个不可判定(undecidable problem)的问题。换句话说,只有开发人员才能明确是否可以将内存返回给操作系统。
某些编程语言提供了帮助开发人员执行此操作的功能,希望开发人员完全明确何时不再使用内存。Wikipedia has good articles on manual and automaticmemory management.
The four types of common JavaScript leaks
1. Global variables
JavaScript 以一种有趣的方式处理未声明的变量:当引用未声明的变量时,会在全局对象中创建一个新变量。在浏览器中,全局对象将是 window,这意味着
function foo ( arg) {
bar = "some text" ;
}
等价于
function foo ( arg) {
window. bar = "some text" ;
}
假设 bar
的目的是仅引用 foo
函数中的变量。但是,如果不使用 var
来声明它,则会创建一个冗余的全局变量。在上述情况下,这不会造成太大伤害。你肯定可以想象一个更具破坏性的场景。
function foo ( ) {
this . var1 = "potential accidental global" ;
}
foo ( ) ;
你可以通过添加 'use strict'
来避免这一切;在 JavaScript 文件的开头,它将打开更严格的解析 JavaScript 模式,以防止意外创建全局变量。
意外的全局变量肯定是个问题,但是,通常情况下,您的代码会被显式的全局变量所侵扰,而这些变量根据定义无法被垃圾收集器收集。需要特别注意用于临时存储和处理大量信息的全局变量。如果必须使用全局变量来存储数据,请确保使用完成后将其指定为null或重新分配它。
2. Timers or callbacks that are forgotten
我们以 setInterval
为例,因为它经常在 JavaScript 中使用.
大多数库都会提供观察者或者其它工具来处理回调函数,在他们自己的实例变为不可访问时,会让回调函数也变为不可访问。不过,下面的代码并不罕见:
var serverData = loadData ( ) ;
setInterval ( function ( ) {
var renderer = document. getElementById ( 'renderer' ) ;
if ( renderer) {
renderer. innerHTML = JSON . stringify ( serverData) ;
}
} , 5000 ) ;
这个例子阐述着 timers 可能发生的情况:计时器会引用不再需要的节点或数据。
renderer
可能在将来会被移除,使得 interval
内的整个块都不再被需要。但是,interval handler
因为 interval
的存活,所以无法被回收(需要停止 interval
,才能回收)。如果 interval handler
无法被回收,则它的依赖也不能被回收。这意味着 serverData
— 可能存储了大量数据,也不能被回收。
在观察者模式下,重要的是在他们不再被需要的时候显式地去删除它们(或者让相关对象变为不可访问)。
幸运的是,大多数现代浏览器都能为您完成这项工作:即使您忘记移除侦听器,一旦观察到的对象无法访问,它们也会自动收集观察者处理程序。在过去,一些浏览器无法处理这些情况(旧的IE6)。
尽管如此,一旦对象变得过时,它仍然符合删除观察者的最佳实践。例如:
var element = document. getElementById ( 'launch-button' ) ;
var counter = 0 ;
function onClick ( event) {
counter++ ;
element. innerHtml = 'text ' + counter;
}
element. addEventListener ( 'click' , onClick) ;
element. removeEventListener ( 'click' , onClick) ;
element. parentNode. removeChild ( element) ;
在使节点无法访问之前,您不再需要调用 removeEventListener
,因为现代浏览器支持可以检测这些循环并适当处理它们的垃圾收集器。
如果利用 jQuery API(其他库和框架也支持它),可以在节点过时之前删除侦听器。即使应用程序在较旧的浏览器版本下运行,该库也将确保没有内存泄漏。
3. Closures
JavaScript 开发的一个关键方面就是闭包:一个可以访问外部(封闭)函数变量的内部函数。由于 JavaScript 运行时的实现细节,可以通过以下方式泄漏内存:
var theThing = null ;
var replaceThing = function ( ) {
var originalThing = theThing;
var unused = function ( ) {
if ( originalThing)
console. log ( "hi" ) ;
} ;
theThing = {
longStr: new Array ( 1000000 ) . join ( '*' ) ,
someMethod: function ( ) {
console. log ( "message" ) ;
}
} ;
} ;
setInterval ( replaceThing, 1000 ) ;
这个代码片段做了一件事:每次调用 replaceThing
时,theThing
都会获得一个新对象,它包含一个大的数组和一个新的闭包(someMethod
)。同时,变量 unused
保留了一个拥有originalThing
引用的闭包(前一次调用 theThing
赋值给了 originalThing
)。已经有点混乱了吗?重要的是,一旦一个作用域被创建为闭包,那么它的父作用域将被共享。
在这个例子中,创建闭包 someMethod
的作用域是于 unused
共享的。unused
拥有 originalThing
的引用。尽管 unused
从来都没有使用,但是 someMethod
能够通过 theThing
在 replaceThing
之外的作用域使用(例如全局范围)。并且由于 someMethod
和 unused
共享闭包作用域,unused
的引用将强制保持 originalThing
处于活动状态(两个闭包之间共享整个作用域),这样防止了垃圾回收。
当这段代码重复执行时,可以观察到内存使用量的稳定增长。当 GC 运行时,也没有变小。实质上,引擎创建了一个闭包的链接列表(root
就是变量 theThing
),并且这些闭包的作用域中每一个都有对大数组的间接引用,导致了相当大的内存泄漏。
This issue was found by the Meteor team and they have a great article that describes the issue in great detail.
4. Out of DOM references
有时候,在数据结构中存储 DOM 结构是有用的。假设要快速更新表中的几行内容。将每行 DOM 的引用存储在字典或数组中可能是有意义的。当这种情况发生时,就会保留同一 DOM 元素的两份引用:一个在 DOM 树中,另一个在字典中。如果将来某个时候你决定要删除这些行,则需要让两个引用都不可达。
var elements = {
button: document. getElementById ( 'button' ) ,
image: document. getElementById ( 'image' )
} ;
function doStuff ( ) {
elements. image. src = 'http://example.com/image_name.png' ;
}
function removeImage ( ) {
document. body. removeChild ( document. getElementById ( 'image' ) ) ;
}
还有一个额外的考虑,当涉及 DOM 树内部或叶子节点的引用时,必须考虑这一点。假设你在 JavaScript 代码中保留了对 table 特定单元格()的引用。有一天,你决定从 DOM 中删除该 table,但扔保留着对该单元格的引用。直观地来看,可以假设 GC 将收集除了该单元格之外所有的内容。实际上,这不会发生的:该单元格是该 table 的子节点,并且 children 保持着对它们 parents 的引用。也就是说,在 JavaScript 代码中对单元格的引用会导致整个表都保留在内存中的。保留 DOM 元素的引用时,需要仔细考虑。
你可能感兴趣的:(JavaScript)
Long类型前后端数据不一致
igotyback
前端
响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问
DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理
STU学生网页设计
网页设计 期末网页作业 html静态网页 html5期末大作业 网页设计 web大作业
️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程
关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript
二挡起步
web前端期末大作业 javascript html css 旅游 风景
⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip
HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动
二挡起步
web前端期末大作业 web设计网页规划与设计 html css javascript dreamweaver 前端
Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线
node.js学习
小猿L
node.js node.js 学习 vim
node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行
JavaScript 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
跳房子的前端
前端面试 javascript 开发语言 ecmascript
在JavaScript中,深拷贝(DeepCopy)和浅拷贝(ShallowCopy)是用于复制对象或数组的两种不同方法。了解它们的区别和应用场景对于避免潜在的bugs和高效地处理数据非常重要。以下是对深拷贝和浅拷贝的详细解释,包括它们的概念、用途、优缺点以及实现方式。1.浅拷贝(ShallowCopy)概念定义:浅拷贝是指创建一个新的对象或数组,其中包含了原对象或数组的基本数据类型的值和对引用数
JavaScript `Map` 和 `WeakMap`详细解释
跳房子的前端
JavaScript 原生方法 javascript 前端 开发语言
在JavaScript中,Map和WeakMap都是用于存储键值对的数据结构,但它们有一些关键的不同之处。MapMap是一种可以存储任意类型的键值对的集合。它保持了键值对的插入顺序,并且可以通过键快速查找对应的值。Map提供了一些非常有用的方法和属性来操作这些数据对:set(key,value):将一个键值对添加到Map中。如果键已经存在,则更新其对应的值。get(key):获取指定键的值。如果键
切换淘宝最新npm镜像源是
hai40587
npm 前端 node.js
切换淘宝最新npm镜像源是一个相对简单的过程,但首先需要明确当前淘宝npm镜像源的状态和最新的镜像地址。由于网络环境和服务更新,镜像源的具体地址可能会发生变化,因此,我将基于当前可获取的信息,提供一个通用的切换步骤,并附上最新的镜像地址(截至回答时)。一、了解npm镜像源npm(NodePackageManager)是JavaScript的包管理器,用于安装、更新和管理项目依赖。由于npm官方仓库
高性能javascript--算法和流程控制
海淀萌狗
-for,while和do-while性能相当-避免使用for-in循环,==除非遍历一个属性量未知的对象==es5:for-in遍历的对象便不局限于数组,还可以遍历对象。原因:for-in每次迭代操作会同时搜索实例或者原型属性,for-in循环的每次迭代都会产生更多开销,因此要比其他循环类型慢,一般速度为其他类型循环的1/7。因此,除非明确需要迭代一个属性数量未知的对象,否则应避免使用for-i
360前端星计划-动画可以这么玩
马小蜗
动画的基本原理定时器改变对象的属性根据新的属性重新渲染动画functionupdate(context){//更新属性}constticker=newTicker();ticker.tick(update,context);动画的种类1、JavaScript动画操作DOMCanvas2、CSS动画transitionanimation3、SVG动画SMILJS动画的优缺点优点:灵活度、可控性、性能
JavaScript中秋快乐!
Q_w7742
javascript 开发语言 ecmascript
我们来实现一个简单的祝福网页~主要的难度在于使用canvas绘图当点击canvas时候,跳出“中秋节快乐”字样,需要注册鼠标单击事件和计时器。首先定义主要函数:初始化当点击canvas之后转到onCanvasClick函数,绘图生成灯笼。functiononCanvasClick(){//事件处理函数context.clearRect(0,0,canvas1.width,canvas1.heigh
Nginx从入门到实践(三)
听你讲故事啊
动静分离动静分离是将网站静态资源(JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。动静分离的一种做法是将静态资源部署在nginx上,后台项目部署到应用服务器上,根据一定规则静态资源的请求全部请求nginx服务器,达到动静分离的目标。rewrite规则Rewrite规则常见正则表达式Rewrite主要的功能就是实现URL的重写,Ngin
Nginx的使用场景:构建高效、可扩展的Web架构
张某布响丸辣
nginx 前端 架构
Nginx,作为当今最流行的Web服务器和反向代理软件之一,凭借其高性能、稳定性和灵活性,在众多Web项目中扮演着核心角色。无论是个人博客、中小型网站,还是大型企业级应用,Nginx都能提供强大的支持。本文将探讨Nginx的几个主要使用场景,帮助读者理解如何在实际项目中充分利用Nginx的优势。1.静态文件服务对于包含大量静态文件(如HTML、CSS、JavaScript、图片等)的网站,Ngin
前端知识点
ZhangTao_zata
前端 javascript css
下面是一个最基本的html代码body{font-family:Arial,sans-serif;margin:20px;}//JavaScriptfunctionthatdisplaysanalertwhencalledfunctionshowMessage(){alert("Hello!Youclickedthebutton.");}MyFirstHTMLPageWelcometoMyPage
【JS】前端文件读取FileReader操作总结
程序员-张师傅
前端 前端 javascript 开发语言
前端文件读取FileReader操作总结FileReader是JavaScript中的一个WebAPI,它允许web应用程序异步读取用户计算机上的文件(或原始数据缓冲区)的内容,例如读取文件以获取其内容,并在不将文件发送到服务器的情况下在客户端使用它。这对于处理图片、文本文件等非常有用,尤其是当你想要在用户界面中即时显示文件内容或进行文件预览时。创建FileReader对象首先,你需要创建一个Fi
webstorm报错TypeError: this.cliEngine is not a constructor
Blue_Color
点击Details在控制台会显示报错的位置TypeError:this.cliEngineisnotaconstructoratESLintPlugin.invokeESLint(/Applications/RubyMine.app/Contents/plugins/JavaScriptLanguage/languageService/eslint/bin/eslint-plugin.js:97:
创建一个完整的购物商城系统是一个复杂的项目,涉及前端(用户界面)、后端(服务器逻辑)、数据库等多个部分。由于篇幅限制,我无法在这里提供一个完整的系统代码,但我可以分别给出一些关键部分的示例代码,涵盖几
uthRaman
前端 ui 服务器
前端(HTML/CSS/JavaScript)grsyzp.cnHTML页面结构(index.html)html购物商城欢迎来到购物商城JavaScript(Ajax请求商品数据,app.js)javascriptdocument.addEventListener('DOMContentLoaded',function(){fetch('/api/products').then(response=
了解 UNPKG:前端开发者的包管理利器
小于负无穷
前端 javascript typescript css html5 node.js
在现代前端开发中,JavaScript包管理和模块化是至关重要的,而npm则是最流行的JavaScript包管理器之一。不过,随着前端项目复杂性的增加,有时候我们希望快速引入外部依赖,而无需本地安装和构建。此时,CDN(内容分发网络)成为了一种方便快捷的解决方案,而UNPKG就是这种方式中的佼佼者。什么是UNPKG?UNPKG是一个基于npm的内容分发网络(CDN),它允许开发者直接通过URL从n
2019-05-29 vue-router的两种模式的区别
Kason晨
1、大家都知道vue是一种单页应用,单页应用就是仅在页面初始化的时候加载相应的html/css/js一单页面加载完成,不会因为用户的操作而进行页面的重新加载或者跳转,用javascript动态的变化html的内容优点:良好的交互体验,用户不需要刷新页面,页面显示流畅,良好的前后端工作分离模式,减轻服务器压力,缺点:不利于SEO,初次加载耗时比较多2、hash模式vue-router默认的是hash
electron多标签页模式更像客户端
diygwcom
electron javascript 前端
Electron多标签页模式是指在Electron框架中实现的类似Web浏览器的多标签页功能。Electron是一个使用Web技术(HTML、CSS和JavaScript)来创建跨平台桌面应用程序的框架。在Electron中实现多标签页模式,通常需要借助一些特定的库或组件,如BrowserView或electron-tabs,或者通过自定义实现。实现方式1.使用BrowserViewBrowser
外卖霸王餐返利外卖会员卡小程序开发
闹小艾
good506070 微信小程序 小程序
外卖霸王餐返利外卖会员卡小程序开发"社交电商赋能下的外卖返利小程序"是专为商家与用户双赢而设计的创新平台。以下是其开发方案的详细步骤:一、需求梳理:首先,我们需要明确小程序的核心功能和特色。包括设定活动类型、返利策略,以及用户体验友好的界面设计。二、技术决策:技术选型是关键。我们采用小程序的开发框架,利用JavaScript作为前端开发语言,并结合微信提供的API进行后端接口调用与数据处理。三、账
Axure设计之全屏与退出全屏交互实现
招风的黑耳
Axure axure 交互
在AxureRP中,设计全屏与退出全屏的交互功能可以极大地提升用户体验,尤其是在展示产品原型或进行演示时。本文将详细介绍如何在AxureRP中通过结合JavaScript代码实现全屏与退出全屏的交互效果。Axure原型设计web端交互元件库:https://1zvcwx.axshare.com一、设计思路全屏与退出全屏的交互设计主要依赖于JavaScript代码来控制浏览器的全屏模式。在Axure
全面指南:用户行为从前端数据采集到实时处理的最佳实践
数字沉思
营销 流量运营 系统架构 前端 内容运营 大数据
引言在当今的数据驱动世界,实时数据采集和处理已经成为企业做出及时决策的重要手段。本文将详细介绍如何通过前端JavaScript代码采集用户行为数据、利用API和Kafka进行数据传输、通过Flink实时处理数据的完整流程。无论你是想提升产品体验还是做用户行为分析,这篇文章都将为你提供全面的解决方案。设计一个通用的ClickHouse表来存储用户事件时,需要考虑多种因素,包括事件类型、时间戳、用户信
EcmaScript和JavaScript的区别
每天吃八顿
前端 ecmascript
ECMAScript和JavaScript是经常被混淆的两个术语,但实际上它们之间存在一些区别:ECMAScript:ECMAScript(通常缩写为ES,并且有版本号如ES5,ES6和ES7等)是由ECMA国际(EuropeanComputerManufacturersAssociation)制定的一种脚本语言的规范。这个规范定义了语法、命令、数据类型等基本元素。ECMAScript是一种规范,
javascript添加p元素,html添加文字,appendChild
游勇一
javascript html添加p appendChild
javascript添加p元素,html添加文字,appendChild。网页添加p元素效果截图。个人签名:游志勇,预制板,南托岭预制场。文字展示#wordsadd{font-size:70px;word-break:break-all;}#wordsaddp{margin:002px0;padding:002px0;line-height:93%;}.btn_width{width:90px;}
CesiumJS+SuperMap3D.js混用实现可视域分析 S3M图层加载 裁剪区域绘制
SteveJi666
WebGL cesium EarthSDK SuperMap 3d javascript 前端 arcgis
版本简介:cesium:1.99;Supermap3D:SuperMapiClientJavaScript11i(2023);官方下载文档链家:SuperMap技术资源中心|为您提供全面的在线技术服务示例参考:support.supermap.com.cn:8090/webgl/Cesium/examples/webgl/examples.html#analysissupport.supermap
html打开本地excel文件夹,html使用excel表格数据库-html读取本地excel文件并展示
睿理
html表格如何导入到excel中在vs里面用添加数据源就可以啊,再使用数据控件,就可以操作.添加数据源可以用odbc数据源,两种方式1,是在控制面板的管理工具里在ODBC里先设置好.2,是使用连接字符串.用vs的添加数据源向导做.html中有没有类似excel表格,可以填数的表格控件?首先html不能读取本地excel文件其次就算是javascript也是不允许的这是为了安全考虑如果前端脚本可以
如何在 Python 中声明一个静态属性?
潮易
python 开发语言
在Python中,静态属性的定义和使用方式与JavaScript中的类似,主要是通过`@staticmethod`装饰器来实现。静态属性不需要实例化对象就可以访问,它们属于类本身。###如何声明一个静态属性:1.首先,需要在属性名前添加`@staticmethod`装饰器。2.接下来,定义一个普通方法,该方法的第一个参数通常为`cls`(用于表示类的引用)。###代码示例:```pythoncla
数据格式:什么是JSON和XML
isNotNullX
json xml
JSON和XML都是数据交换的一种格式,用于在不同的系统和应用程序之间传输和存储数据。本文将解释JSON和XML的基础内容,并探讨两者的不同。一·什么是JSON?1.JSON(JavaScriptObjectNotation)即JavaScript对象标记法:-JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。-JSON基于JavaScript的一个子集,但JSON是
HighCharts图表自动化简介
知识的宝藏
Selenium高级篇 Selenium图表自动化测试 highcharts图表自动化 Selenium图表自动化 图表自动化测试 highcharts Selenium
什么是分析数据?在任何应用程序中捕获并以图形或图表形式显示的分析数据是任何产品或系统的关键部分,因为它提供了对实时数据的洞察。验证此类分析数据非常重要,因为不准确的数据可能会在报告中产生问题,并可能影响应用程序/系统的其他相关领域。什么是HighChart?Highcharts是一个用纯JavaScript编写的j基于SVG成图技术的图表库,提供了一种简单的方法来向您的网站或Web应用程序添加交互
关于旗正规则引擎中的MD5加密问题
何必如此
jsp MD5 规则 加密
一般情况下,为了防止个人隐私的泄露,我们都会对用户登录密码进行加密,使数据库相应字段保存的是加密后的字符串,而非原始密码。
在旗正规则引擎中,通过外部调用,可以实现MD5的加密,具体步骤如下:
1.在对象库中选择外部调用,选择“com.flagleader.util.MD5”,在子选项中选择“com.flagleader.util.MD5.getMD5ofStr({arg1})”;
2.在规
【Spark101】Scala Promise/Future在Spark中的应用
bit1129
Promise
Promise和Future是Scala用于异步调用并实现结果汇集的并发原语,Scala的Future同JUC里面的Future接口含义相同,Promise理解起来就有些绕。等有时间了再仔细的研究下Promise和Future的语义以及应用场景,具体参见Scala在线文档:http://docs.scala-lang.org/sips/completed/futures-promises.html
spark sql 访问hive数据的配置详解
daizj
spark sql hive thriftserver
spark sql 能够通过thriftserver 访问hive数据,默认spark编译的版本是不支持访问hive,因为hive依赖比较多,因此打的包中不包含hive和thriftserver,因此需要自己下载源码进行编译,将hive,thriftserver打包进去才能够访问,详细配置步骤如下:
1、下载源码
2、下载Maven,并配置
此配置简单,就略过
HTTP 协议通信
周凡杨
java httpclient http 通信
一:简介
HTTPCLIENT,通过JAVA基于HTTP协议进行点与点间的通信!
二: 代码举例
测试类:
import java
java unix时间戳转换
g21121
java
把java时间戳转换成unix时间戳:
Timestamp appointTime=Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:m
web报表工具FineReport常用函数的用法总结(报表函数)
老A不折腾
web报表 finereport 总结
说明:本次总结中,凡是以tableName或viewName作为参数因子的。函数在调用的时候均按照先从私有数据源中查找,然后再从公有数据源中查找的顺序。
CLASS
CLASS(object):返回object对象的所属的类。
CNMONEY
CNMONEY(number,unit)返回人民币大写。
number:需要转换的数值型的数。
unit:单位,
java jni调用c++ 代码 报错
墙头上一根草
java C++ jni
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000777c3290, pid=5632, tid=6656
#
# JRE version: Java(TM) SE Ru
Spring中事件处理de小技巧
aijuans
spring Spring 教程 Spring 实例 Spring 入门 Spring3
Spring 中提供一些Aware相关de接口,BeanFactoryAware、 ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等,其中最常用到de匙ApplicationContextAware.实现ApplicationContextAwaredeBean,在Bean被初始后,将会被注入 Applicati
linux shell ls脚本样例
annan211
linux linux ls源码 linux 源码
#! /bin/sh -
#查找输入文件的路径
#在查找路径下寻找一个或多个原始文件或文件模式
# 查找路径由特定的环境变量所定义
#标准输出所产生的结果 通常是查找路径下找到的每个文件的第一个实体的完整路径
# 或是filename :not found 的标准错误输出。
#如果文件没有找到 则退出码为0
#否则 即为找不到的文件个数
#语法 pathfind [--
List,Set,Map遍历方式 (收集的资源,值得看一下)
百合不是茶
list set Map遍历方式
List特点:元素有放入顺序,元素可重复
Map特点:元素按键值对存储,无放入顺序
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
List接口有三个实现类:LinkedList,ArrayList,Vector
LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身
解决SimpleDateFormat的线程不安全问题的方法
bijian1013
java thread 线程安全
在Java项目中,我们通常会自己写一个DateUtil类,处理日期和字符串的转换,如下所示:
public class DateUtil01 {
private SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void format(Date d
http请求测试实例(采用fastjson解析)
bijian1013
http 测试
在实际开发中,我们经常会去做http请求的开发,下面则是如何请求的单元测试小实例,仅供参考。
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import
【RPC框架Hessian三】Hessian 异常处理
bit1129
hessian
RPC异常处理概述
RPC异常处理指是,当客户端调用远端的服务,如果服务执行过程中发生异常,这个异常能否序列到客户端?
如果服务在执行过程中可能发生异常,那么在服务接口的声明中,就该声明该接口可能抛出的异常。
在Hessian中,服务器端发生异常,可以将异常信息从服务器端序列化到客户端,因为Exception本身是实现了Serializable的
【日志分析】日志分析工具
bit1129
日志分析
1. 网站日志实时分析工具 GoAccess
http://www.vpsee.com/2014/02/a-real-time-web-log-analyzer-goaccess/
2. 通过日志监控并收集 Java 应用程序性能数据(Perf4J)
http://www.ibm.com/developerworks/cn/java/j-lo-logforperf/
3.log.io
和
nginx优化加强战斗力及遇到的坑解决
ronin47
nginx 优化
先说遇到个坑,第一个是负载问题,这个问题与架构有关,由于我设计架构多了两层,结果导致会话负载只转向一个。解决这样的问题思路有两个:一是改变负载策略,二是更改架构设计。
由于采用动静分离部署,而nginx又设计了静态,结果客户端去读nginx静态,访问量上来,页面加载很慢。解决:二者留其一。最好是保留apache服务器。
来以下优化:
java-50-输入两棵二叉树A和B,判断树B是不是A的子结构
bylijinnan
java
思路来自:
http://zhedahht.blog.163.com/blog/static/25411174201011445550396/
import ljn.help.*;
public class HasSubtree {
/**Q50.
* 输入两棵二叉树A和B,判断树B是不是A的子结构。
例如,下图中的两棵树A和B,由于A中有一部分子树的结构和B是一
mongoDB 备份与恢复
开窍的石头
mongDB备份与恢复
Mongodb导出与导入
1: 导入/导出可以操作的是本地的mongodb服务器,也可以是远程的.
所以,都有如下通用选项:
-h host 主机
--port port 端口
-u username 用户名
-p passwd 密码
2: mongoexport 导出json格式的文件
[网络与通讯]椭圆轨道计算的一些问题
comsci
网络
如果按照中国古代农历的历法,现在应该是某个季节的开始,但是由于农历历法是3000年前的天文观测数据,如果按照现在的天文学记录来进行修正的话,这个季节已经过去一段时间了。。。。。
也就是说,还要再等3000年。才有机会了,太阳系的行星的椭圆轨道受到外来天体的干扰,轨道次序发生了变
软件专利如何申请
cuiyadll
软件专利 申请
软件技术可以申请软件著作权以保护软件源代码,也可以申请发明专利以保护软件流程中的步骤执行方式。专利保护的是软件解决问题的思想,而软件著作权保护的是软件代码(即软件思想的表达形式)。例如,离线传送文件,那发明专利保护是如何实现离线传送文件。基于相同的软件思想,但实现离线传送的程序代码有千千万万种,每种代码都可以享有各自的软件著作权。申请一个软件发明专利的代理费大概需要5000-8000申请发明专利可
Android学习笔记
darrenzhu
android
1.启动一个AVD
2.命令行运行adb shell可连接到AVD,这也就是命令行客户端
3.如何启动一个程序
am start -n package name/.activityName
am start -n com.example.helloworld/.MainActivity
启动Android设置工具的命令如下所示:
# am start -
apache虚拟机配置,本地多域名访问本地网站
dcj3sjt126com
apache
现在假定你有两个目录,一个存在于 /htdocs/a,另一个存在于 /htdocs/b 。
现在你想要在本地测试的时候访问 www.freeman.com 对应的目录是 /xampp/htdocs/freeman ,访问 www.duchengjiu.com 对应的目录是 /htdocs/duchengjiu。
1、首先修改C盘WINDOWS\system32\drivers\etc目录下的
yii2 restful web服务[速率限制]
dcj3sjt126com
PHP yii2
速率限制
为防止滥用,你应该考虑增加速率限制到您的API。 例如,您可以限制每个用户的API的使用是在10分钟内最多100次的API调用。 如果一个用户同一个时间段内太多的请求被接收, 将返回响应状态代码 429 (这意味着过多的请求)。
要启用速率限制, [[yii\web\User::identityClass|user identity class]] 应该实现 [[yii\filter
Hadoop2.5.2安装——单机模式
eksliang
hadoop hadoop单机部署
转载请出自出处:http://eksliang.iteye.com/blog/2185414 一、概述
Hadoop有三种模式 单机模式、伪分布模式和完全分布模式,这里先简单介绍单机模式 ,默认情况下,Hadoop被配置成一个非分布式模式,独立运行JAVA进程,适合开始做调试工作。
二、下载地址
Hadoop 网址http:
LoadMoreListView+SwipeRefreshLayout(分页下拉)基本结构
gundumw100
android
一切为了快速迭代
import java.util.ArrayList;
import org.json.JSONObject;
import android.animation.ObjectAnimator;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayo
三道简单的前端HTML/CSS题目
ini
html Web 前端 css 题目
使用CSS为多个网页进行相同风格的布局和外观设置时,为了方便对这些网页进行修改,最好使用( )。http://hovertree.com/shortanswer/bjae/7bd72acca3206862.htm
在HTML中加入<table style=”color:red; font-size:10pt”>,此为( )。http://hovertree.com/s
overrided方法编译错误
kane_xie
override
问题描述:
在实现类中的某一或某几个Override方法发生编译错误如下:
Name clash: The method put(String) of type XXXServiceImpl has the same erasure as put(String) of type XXXService but does not override it
当去掉@Over
Java中使用代理IP获取网址内容(防IP被封,做数据爬虫)
mcj8089
免费代理IP 代理IP 数据爬虫 JAVA设置代理IP 爬虫封IP
推荐两个代理IP网站:
1. 全网代理IP:http://proxy.goubanjia.com/
2. 敲代码免费IP:http://ip.qiaodm.com/
Java语言有两种方式使用代理IP访问网址并获取内容,
方式一,设置System系统属性
// 设置代理IP
System.getProper
Nodejs Express 报错之 listen EADDRINUSE
qiaolevip
每天进步一点点 学习永无止境 nodejs 纵观千象
当你启动 nodejs服务报错:
>node app
Express server listening on port 80
events.js:85
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at exports._errnoException (
C++中三种new的用法
_荆棘鸟_
C++ new
转载自:http://news.ccidnet.com/art/32855/20100713/2114025_1.html
作者: mt
其一是new operator,也叫new表达式;其二是operator new,也叫new操作符。这两个英文名称起的也太绝了,很容易搞混,那就记中文名称吧。new表达式比较常见,也最常用,例如:
string* ps = new string("
Ruby深入研究笔记1
wudixiaotie
Ruby
module是可以定义private方法的
module MTest
def aaa
puts "aaa"
private_method
end
private
def private_method
puts "this is private_method"
end
end