标签: JavaScript

JavaScript 多文件下载

3.iframe方式 兼容多种浏览器

function IEdownloadFile(fileName, contentOrPath){
var ifr = document.createElement(‘iframe’);
ifr.style.display = ‘none’;
ifr.src = contentOrPath;
document.body.appendChild(ifr);
// 保存页面 -> 保存文件
ifr.contentWindow.document.execCommand(‘SaveAs’, false, fileName);
document.body.removeChild(ifr);
}

//图片类型保存

var isImg = contentOrPath.slice(0, 10) ===
“data:image”

// dataURL 的情况

isImg && ifr.contentWindow.document.write(
“<span style=”
font-family: Arial, Verdana, sans-serif;
“>”
);</span>

1.h5方式 模拟点击 不支持ie

function downloadFile(fileName, content){
var aLink = document.createElement(‘a’);
, blob = new Blob([content])
, evt = document.createEvent(“HTMLEvents”);

evt.initEvent(“click”);

aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.dispatchEvent(evt);
}
2.打开新窗口 模拟保存 不支持360 搜狗等安全浏览器

// 将文件在一个 window 窗口中打开,并隐藏这个窗口。
var win = window.open(“path/to/file.ext”, “new Window”, “width=0,height=0”);
// 在 win 窗口中按下 ctrl+s 保存窗口内容
win.document.execCommand(“SaveAs”, true, “filename.ext”);
// 使用完了,关闭窗口
win.close();

 

如何解释这段 JavaScript 代码的输出结果?

演示地址: https://jsbin.com/sepapegiga/edit?html,js,console,output

JavaScript href 演示 代码20 条回复 • 2021-07-01 12:16:02 +08:00
pcslide 1
pcslide 16 小时 40 分钟前
这里是个 array of function

这里的 rule 只是一个入参的代号,并不是一个变量
lujjjh 2
lujjjh 16 小时 34 分钟前
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
mxT52CRuqR6o5 3
mxT52CRuqR6o5 16 小时 24 分钟前 via Android ❤️ 1
又不是全局变量,为什么会被覆盖
farmer001 4
farmer001 16 小时 21 分钟前
因为每次函数执行都是不同的作用域(上下文?),所以并不会覆盖
KyrieJoshua 5
KyrieJoshua 16 小时 13 分钟前
内部函数可以访问外层函数的作用域里的变量,我是这么理解的;
定义的时候匿名函数的 rule 就是访问的外部函数里的变量;而且外部函数每次执行的时候都会重新声明一次 rule,所以不会互相覆盖;可以在匿名函数里打断点来查看调用栈;
如果使用 this.rule 来保存就会不一样了
JerryCha 6
JerryCha 16 小时 9 分钟前
似乎形成闭包了
ThomasTrainset 7
ThomasTrainset 16 小时 4 分钟前 via iPhone
基础不扎实
KrisWuSkrSkr 8
KrisWuSkrSkr 15 小时 47 分钟前
我的理解是闭包了,保存了当时的上下文 rule 。
tinkerer 9
tinkerer 14 小时 40 分钟前
2 楼正解。
Rocketer 10
Rocketer 14 小时 35 分钟前 via iPhone
你每次执行 add 方法都声明了一个新的 rule,所以他们各自引用的是不同的对象

Biwood 11
Biwood 14 小时 6 分钟前 via Android
没有立即执行函数和 return 操作很多人就不认识闭包了

按照闭包的解释,每次执行.add 操作的时候,在其内部会形成**一个独立的词法环境**,在这个词法环境中新创建的匿名函数(被 push 那个)会记住对环境中变量的引用,因为你在函数里内部执行了 console.log(rule),用到了当时环境中的 rule,所以这个 rule 变量会跟函数绑在一起,形成闭包

你第二次执行 add 操作的时候,形成的是新的运行时上下文,push 进去的函数也是新的,该函数捆绑的变量也是新的,也就是一个新的闭包,所以不会覆盖上一次用到的变量

你可以在 Chrome 的调试工具里用 console.dir()把*后一步 forEach 中的 fn 打印出来,可以看到闭包里面具体引用了哪些内容
muzuiget 12
muzuiget 12 小时 54 分钟前
闭包,建议重新理解。
myCupOfTea 13
myCupOfTea 5 小时 5 分钟前
这不就是闭包吗
meepo3927 14
meepo3927 5 小时 3 分钟前
形成闭包了,匿名函数访问的变量 Rule 不会释放。

每次执行 add 方法,都会存储一个新的 Rule 变量以及值,通常在方法结束之后,这个变量会被释放,

但是有闭包的情况,不会释放。
zhanlanhuizhang 15
zhanlanhuizhang 4 小时 39 分钟前
基本知识,没学好。
sandman511 16
sandman511 4 小时 23 分钟前
我后端,光看个标题就知道是闭包问题了(狗头
no1xsyzy 17
no1xsyzy 4 小时 18 分钟前
我还在想有什么可解释的,竟然是在说作用域?

请回炉从 SICP 重造
cenbiq 18
cenbiq 4 小时 7 分钟前
就是不会被覆盖,因为两次执行了 add 方法,var rule 发生了两次
lizhenda 19
lizhenda 4 小时 5 分钟前
闭包
libook 20
libook 1 小时 33 分钟前
function 其实有两种调用模式,一种是函数,另一种是对象方法;不同调用模式表现出不同的特性,*直接的区别就是 function 运行的上下文。

add 是声明在 RuleSystem 类(或者说是 RuleSystem 构造函数的原型)上的,当 new 出一个 ruleSystem 对象的时候,调用 ruleSystem.add 就是调用对象方法的模式,它的上下文是 ruleSystem 对象本身,所能直接操作 ruleSystem 的 rules 数组。

在 add 方法内部向 rules push 的 item 是个 funciton,这个 funciton 不在原型链上,调用的时候是普通的函数调用模式,所以它的上下文是它所在的作用域(跟写 C 语言差不多),用到 rule 的时候就会自然向外层一层一层搜索 rule 这个关键字,于是找到了 var rule=’Rule ‘+rule 。

当你每次调用 add 方法的时候,都会产生一个新的局部作用域,这个作用域里有个 rule 变量,你一共调用了 2 次 add 方法,所以创建了 2 个局部作用域,这两个作用域里的 rule 值不一样,一个是”Rule A”,另一个是”Rule B”;两次 push 也都是在上述两个作用域里分别执行的,push 到 rules 的 function 里的 rule 也都是引用各自作用域里离它*近的那个 rule 。

这时候代码等价于:

var rules=[];

var add=function(rule){
var rule=’Rule ‘+rule
rules.push(function(){
console.log(rule)
})
}

两者区别仅仅是 rules 放在对象里还是直接放在上层作用域里,其余都是完全等价的。

如果你希望 rules 数组里的所有函数中的 console.log(rule)都输出*后产生的 rule 值,你应该把 add 方法内部的 rule 变量换成一个公共变量,就是每次调用 add 方法不会重新创建的那种,比如直接放在上层作用域里,或者用 this.rule 。

【前端面试题】关于性能优化的面试题(附答案)

%title插图%num

随着前端项目不断扩大,浏览器渲染的压力变得越来越重。配置好一点的计算机可以顺利地展现页面;配置低一些的计算机渲染页面的性能就不那么可观了。

性能优化部分的面试题主要考察应试者对网站性能优化的了解。如何做好性能优化,哪些操作会引起性能优化的问题,性能优化指标是什么等,都值得应试者关注。

因为性能优化变得越来越重要,所以很多企业专门建立团队去做性能优化。

1、谈谈你对重构的理解。

网站重构是指在不改变外部行为的前提下,简化结构、添加可读性,且在网站前端保持一致的行为。也就是说,在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。

对于传统的网站来说,重构通常包括以下方面。

  • 把表格( table)布局改为DV+CSS。
  • 使网站前端兼容现代浏览器。
  • 对移动平台进行优化。
  • 针对搜索引擎进行优化。

深层次的网站重构应该考虑以下方面。

  • 减少代码间的耦合
  • 让代码保持弹性。
  • 严格按规范编写代码。
  • 设计可扩展的API。
  • 代替旧的框架、语言(如VB)
  • 增强用户体验。
  • 对速度进行优化。
  • 压缩 JavaScript、CSS、 image等前端资源(通常由服务器来解决)。
  • 优化程序的性能(如数据读写)。
  • 采用CDN来加速资源加载。
  • 优化 JavaScript DOM。
  • 缓存HTTP服务器的文件。

2、如果一个页面上有大量的图片(大型电商网站),网页加载很慢,可以用哪些方法优化这些图片的加载,从而提升用户体验?

对于图片懒加载,可以为页面添加一个滚动条事件,判断图片是否在可视区域内或者即将进入可视区域,优先加载。

如果为幻灯片、相册文件等,可以使用图片预加载技术,对于当前展示图片的前一张图片和后一张图片优先下载。

如果图片为CSS图片,可以使用 CSS Sprite、SVG sprite、 Icon font、Base64等技术。

如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩得特别小的缩略图,以提高用户体验。

如果图片展示区域小于图片的真实大小,则应在服务器端根据业务需要先行进行图片压缩,图片压缩后,图片大小与展示的就一致了。

3、谈谈性能优化问题。

可以在以下层面优化性能。

  • 缓存利用:缓存Ajax,使用CDN、外部 JavaScript和CSS文件缓存,添加 Expires头,在服务器端配置Etag,减少DNS查找等。
  • 请求数量:合并样式和脚本,使用CSS图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
  • 请求带宽:压缩文件,开启GZIP 。
  • CSS代码:避免使用CSS表达式、高级选择器、通配选择器。
  • JavaScript代码:用散列表来优化查找,少用全局变量,用 innerHTML代替DOM操作,减少DOM操作次数,优化 JavaScript性能,用 setTimeout避免页面失去响应,缓存DOM节点查找的结果,避免使用with(with会创建自己的作用域,增加作用域链的长度),多个变量声明合并。
  • HTML代码:避免图片和 iFrame等src属性为空。src属性为空,会重新加载当前页面,影响速度和效率,尽量避免在HTML标签中写 Style属性

4、移动端性能如何优化?

优化方式如下。

  • 尽量使用CSS3动画,开启硬件加速。
  • 适当使用 touch事件代替 click事件。
  • 避免使用CSS3渐变阴影效果。
  • 可以用 transform:translateZ(0)来开启硬件加速。
  • 不滥用 Float, Float在渲染时计算量比较大,尽量少使用。
  • 不滥用Web字体,Web字体需要下载、解析、重绘当前页面,尽量少使用。
  • 合理使用requestAnimation Frame动画代替 setTimeout。
  • 合理使用CSS中的属性(CSS3 transitions、CSS3 3D transforms、 Opacity、 Canvas、 WebGL、Video)触发GPU渲染。过度使用会使手机耗电量増加。

5、如何对网站的文件进行优化?

可以进行文件合并、文件压缩使文件*小化;可以使用CDN托管文件,让用户更快速地访问;可以使用多个域名来缓存静态文件。

6、请说出几种缩短页面加载时间的方法。

具体方法如下。

(1)优化图片

(2)选择图像存储格式(比如,GIF提供的颜色较少,可用在一些对颜色要求不高的地方)

(3)优化CSS(压缩、合并CSS)

(4)在网址后加斜杠

(5)为图片标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小。如果图片很多,浏览器需要不断地调整页面。这不但影响速度,而且影响浏览体验。当浏览器知道高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容,从而优化加载时间,提升浏览体验)。

7、哪些方法可以提升网站前端性能?

精灵图合并,减少HTTP请求;压缩HTML、CSS、JavaScript文件;使用CDN托管静态文件;使用 localstorage缓存和 mainfest应用缓存。

8、你知道哪些优化性能的方法?

具体方法如下。

(1)减少HTTP请求次数,控制CSS Sprite、JavaScript与CSS源码、图片的大小,使用网页Gzip、CDN托管、data缓存、图片服务器

(2)通过前端模板 JavaScript和数据,减少由于HTML标签导致的带宽浪费,在前端用变量保存Ajax请求结果,每次操作本地变量时,不用请求,减少请求次数。

(3)用 innerhTML代替DOM操作,减少DOM操作次数,优化 JavaScript性能。

(4)当需要设置的样式很多时,设置 className而不是直接操作 Style。

(5)少用全局变量,缓存DOM节点查找的结果,减少I/O读取操作

(6)避免使用CSS表达式,它又称动态属性,

(7)预加载图片,将样式表放在顶部,将脚本放在底部,加上时间戳。

(8)避免在页面的主体布局中使用表,表要在其中的内容完全下载之后才会显示出来,显示的速度比DIV+CSS布局慢。

9、列举你知道的Web性能优化方法。

具体优化方法如下。

(1)压缩源码和图片( JavaScript采用混淆压缩,CSS进行普通压缩,JPG图片根据具体质量压缩为50%~70%,把PNG图片从24色压缩成8色以去掉一些PNG格式信息等)。

(2)选择合适的图片格式(颜色数多用JPG格式,而很少使用PNG格式,如果能通过服务器端判断浏览器支持WebP就用WebP或SVG格式)。

(3)合并静态资源(减少HTTP请求)

(4)把多个CSS合并为一个CSS,把图片组合成雪碧图。

(5)开启服务器端的Gzip压缩(对文本资源非常有效)。

(6)使用CDN(对公开库共享缓存)。

(7)延长静态资源缓存时间。

(8)把CSS放在页面头部把 JavaScript代码放在页面底部(这样避免阻塞页面渲染而使页面出现长时间的空白)

10、平时你是如何对代码进行性能优化的?

利用性能分析工具监测性能,包括静态 Analyze工具和运行时的 Profile工具(在Xcode工具栏中依次单击 Product→ Profile项可以启动)。

比如测试程序的运行时间,当单击 Time Profiler项时,应用程序开始运行,这就能获取到运行整个应用程序所消耗时间的分布和百分比。为了保证数据分析在同一使用场景下的真实性,一定要使用真机,因为此时模拟器在Mac上运行,而Mac上的CPU往往比iOS设备要快。

11、针对CSS,如何优化性能?

具体优化方法如下。

(1)正确使用 display属性, display属性会影响页面的渲染,因此要注意以下几方面。

display:inline后不应该再使用 width、 height、 margin、 padding和float 。

display:inline- block后不应该再使用 float。

display:block后不应该再使用 vertical-align。

display:table-*后不应该再使用 margin或者float。

(2)不滥用 float。

(3)不声明过多的font-size。

(4)当值为0时不需要单位。

(5)标准化各种浏览器前缀,并注意以下几方面。

  • 浏览器无前缀应放在*后。
  • CSS动画只用( -webkit-无前缀)两种即可。
  • 其他前缀包括 -webkit-、-moz-、-ms-、无前缀( Opera浏览器改用 blink内核,所以-0-被淘汰)

(6)避免让选择符看起来像是正则表达式。高级选择器不容易读懂,执行时间也长。

(7)尽量使用id、 class选择器设置样式(避免使用 style属性设置行内样式)

(8)尽量使用CSS3动画。

(9)减少重绘和回流。

12、针对HTML,如何优化性能?

具体方法如下。

(1)对于资源加载,按需加载和异步加载

(2)首次加载的资源不超过1024KB,即越小越好。

(3)压缩HTML、CSS、 JavaScript文件。

(4)减少DOM节点。

(5)避免空src(空src在部分浏览器中会导致无效请求)。

(6)避免30*、40*、50*请求错误

(7)添加 Favicon.ico,如果没有设置图标ico,则默认的图标会导致发送一个404或者500请求。

13、针对 JavaScript,如何优化性能?

具体方法如下。

(1)缓存DOM的选择和计算。

(2)尽量使用事件委托模式,避免批量绑定事件。

(3)使用 touchstart、 touchend代替 click。

(4)合理使用 requestAnimationFrame动画代替 setTimeOut。

(5)适当使用 canvas动画。

(6)尽量避免在高频事件(如 TouchMove、 Scroll事件)中修改视图,这会导致多次渲染。

14、如何优化服务器端?

具体方法如下。

(1)启用Gzip压缩。

(2)延长资源缓存时间,合理设置资源的过期时间,对于一些长期不更新的静态资源过期时间设置得长一些。

(3)减少 cookie头信息的大小,头信息越大,资源传输速度越慢。

(4)图片或者CSS、 JavaScript文件均可使用CDN来加速。

15、如何优化服务器端的接口?

具体方法如下。

(1)接口合并:如果一个页面需要请求两部分以上的数据接口,则建议合并成一个以减少HTTP请求数。

(2)减少数据量:去掉接口返回的数据中不需要的数据。

(3)缓存数据:首次加载请求后,缓存数据;对于非首次请求,优先使用上次请求的数据,这样可以提升非首次请求的响应速度。

16、如何优化脚本的执行?

脚本处理不当会阻塞页面加载、渲染,因此在使用时需注意。

(1)把CSS写在页面头部,把 JavaScript程序写在页面尾部或异步操作中。

(2)避免图片和 iFrame等的空src,空src会重新加载当前页面,影响速度和效率。

(3)尽量避免重设图片大小。重设图片大小是指在页面、CSS、 JavaScript文件等中多次重置图片大小,多次重设图片大小会引发图片的多次重绘,影响性能

(4)图片尽量避免使用 DataURL。DataURL图片没有使用图片的压缩算法,文件会变大,并且要在解码后再渲染,加载慢,耗时长。

17、如何优化渲染?

具体方法如下。

通过HTML设置 Viewport元标签, Viewport可以加速页面的渲染,如以下代码所示。

<meta name="viewport" content="width=device=width,initial-scale=1">

(2)减少DOM节点数量,DOM节点太多会影响页面的渲染,应尽量减少DOM节点数量。

(3)尽量使用CSS3动画,合理使用 requestAnimationFrame动画代替 setTimeout,适当使用 canvas动画(5个元素以内使用CSS动画,5个元素以上使用 canvas动画(iOS 8中可使用 webGL))。

(4)对于高频事件优化 Touchmove, Scroll事件可导致多次渲染。

使用 requestAnimationFrame监听帧变化,以便在正确的时间进行渲染,增加响应变化的时间间隔,减少重绘次数。

使用节流模式(基于操作节流,或者基于时间节流),减少触发次数。

(5)提升GPU的速度,用CSS中的属性(CSS3 transitions、CSS3 3D transforms、 Opacity、 Canvas、 WebGL、Video)来触发GPU渲染.

18、如何设置DNS缓存?

在浏览器地址栏中输入URL以后,浏览器首先要查询域名( hostname)对应服务器的IP地址,一般需要耗费20~120ms的时间。

DNS查询完成之前,浏览器无法识别服务器IP,因此不下载任何数据。基于性能考虑,ISP运营商、局域网路由、操作系统、客户端(浏览器)均会有相应的DNS缓存机制。

(1)正IE缓存30min,可以通过注册表中 DnsCacheTimeout项设置。

(2) Firefox混存1 min,通过 network.dnsCacheExpiration配置。

(3)在 Chrome中通过依次单击“设置”→“选项”→“高级选项”,并勾选“用预提取DNS提高网页载入速度”选项来配置缓存时间。

19、什么时候会出现资源访问失败?

开发过程中,发现很多开发者没有设置图标,而服务器端根目录也没有存放默认的 Favicon.ico,从而导致请求404出现。通常在App的 webview里打开 Favicon.ico,不会加载这个 Favicon.ico,但是很多页面能够分享。

如果用户在浏览器中打开 Favicon. ico,就会调取失败,一般尽量保证该图标默认存在,文件尽可能小,并设置一个较长的缓存过期时间。另外,应及时清理缓存过期导致岀现请求失败的资源。

20、jQuery性能优化如何做?

优化方法如下。

(1)使用*新版本的 jQuery类库。

JQuery类库每一个新的版本都会对上一个版本进行Bug修复和一些优化,同时也会包含一些创新,所以建议使用*新版本的 jQuery类库提高性能。不过需要注意的是,在更换版本之后,不要忘记测试代码,毕竟有时候不是完全向后兼容的。

(2)使用合适的选择器。

jQuery提供非常丰富的选择器,选择器是开发人员*常使用的功能,但是使用不同选择器也会带来性能问题。建议使用简凖选择器,如i选择器、类选择器,不要将i选择器嵌套等。

(3)以数组方式使用 jQuery对象。

使用 jQuery选择器获取的结果是一个 jQuery对象。然而, jQuery类库会让你感觉正在使用一个定义了索引和长度的数组。在性能方面,建议使用简单的for或者 while循环来处理,而不是$. each(),这样能使代码更快。

(4)每一个 JavaScript事件(例如 click、 mouseover等)都会冒泡到父级节点。当需要给多个元素绑定相同的回调函数时,建议使用事件委托模式。

(5)使用join( )来拼接字符串。

使用 join( )拼接长字符串,而不要使用“+”拼接字符串,这有助于性能优化,特别是处理长字符串的时候。

(6)合理利用HTML5中的data属性。

HTML5中的data属性有助于插入数据,特别是前、后端的数据交换;jQuery的 data( )方法能够有效地利用HTML5的属性来自动获取数据。

21、哪些方法能提升移动端CSS3动画体验?

(1)尽可能多地利用硬件能力,如使用3D变形来开启GPU加速,例如以下代码。

  1. -webkit-transform: translate 3d(0, 0, 0);
  2. -moz-transform : translate3d(0,0, 0);
  3. -ms-transform : translate 3d(0,0,0);
  4. transform: translate3d(0,0,0);

一个元素通过 translate3d右移500X的动画流畅度会明显优于使用left属性实现的动画移动,原因是CSS动画属性会触发整个页面重排、重绘、重组。paint通常是*耗性能的,尽可能避免使用触发 paint的CSS动画属性。

如果动画执行过程中有闪烁(通常发生在动画开始的时候),可以通过如下方式处理。

  1. -webkit-backface-visibility:hidden;
  2. -moz-backface-visibility:hidden;
  3. -ms-backface-visibility:hidden ;
  4. backface-visibility:hidden;
  5. -webkit-perspective:1000;
  6. -moz-perspective:1000;
  7. -ms-perspective:1000;
  8. perspective:1000;

(2)尽可能少使用box- shadows和 gradients,它们往往严重影响页面的性能,尤其是在一个元素中同时都使用时。

(3)尽可能让动画元素脱离文档流,以减少重排,如以下代码所示。

  1. position:fixed
  2. position:absolute;

本文完〜

常见JavaScript基础面试题上(附答案)

JavaScript一直都是前端面试的重头戏,也是*核心的部分。JavaScript也是囊括知识点*多的部分,从BOM到DOM,从 ECMAScript编程到简单算法的实现等,都是 JavaScript部分面试题主要考察的内容。
当然,这里的重中之重当属事件和DOM操作,这也是 JavaScript的核心部分。在 ECMAScript中,小到运算符,大到函数的闭包、作用域,以及原型链等都是应试者必须掌握的技术知识。
今天我们为大家准备了一些常见的JavaScript基础面试题,一共有200多道题,因为内容比较多,我们拆分为上下两篇,今天这篇里一共有100道面试题。

1、JavaScript有哪些垃圾回收机制?

有以下垃圾回收机制。

标记清除( mark and sweep)

这是 JavaScript*常见的垃圾回收方式。当变量进入执行环境的时候,比如在函数中声明一个变量,垃圾回收器将其标记为“进入环境”。当变量离开环境的时候(函数执行结束),将其标记为“离开环境”。

垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量,以及被环境中变量所引用的变量(闭包)的标记。在完成这些之后仍然存在的标记就是要删除的变量。

引用计数( reference counting)

在低版本的E中经常会发生内存泄漏,很多时候就是因为它采用引用计数的方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数。

当声明了一个变量并将个引用类型赋值给该变量的时候,这个值的引用次数就加1.如果该变量的值变成了另外一个,则这个值的引用次数减1.当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问。

因此,可以将它占用的空间回收,这样垃圾回收器会在运行的时候清理引用次数为0的值占用的空间在正中虽然 JavaScript对象通过标记清除的方式进行垃圾回收,但是BOM与DOM对象是用引用计数的方式回收垃圾的。

也就是说,只要涉及BOM和DOM,就会出现循环引用问题

2、列举几种类型的DOM节点

有以下几类DOM节点。

整个文档是一个文档( Document)节点。

每个HTML标签是一个元素( Element)节点。

每一个HTML属性是一个属性( Attribute)节点。

包含在HTML元素中的文本是文本(Text)节点。

3、谈谈 script标签中 defer和 async属性的区别。

区别如下。

(1) defer属性规定是否延迟执行脚本,直到页面加载为止, async属性规定脚本一旦可用,就异步执行。

(2) defer并行加载 JavaScript文件,会按照页面上 script标签的顺序执行, async并行加载 JavaScript文件,下载完成立即执行,不会按照页面上 script标签的顺序执行。

4、说说你对闭包的理解。

使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染;缺点是闭包会常驻内存,增加内存使用量,使用不当很容易造成内存泄漏。在JavaScript中,函数即闭包,只有函数才会产生作用域闭包有3个特性

(1)函数嵌套函数。

(2)在函数内部可以引用外部的参数和变量

(3)参数和变量不会以垃圾回收机制回收

5、解释一下 unshift0方法。

该方法在数组启动时起作用,与 push()不同。它将参数成员添加到数组的顶部下面给出一段示例代。

var name=["john"] name. unshift("charlie");name.unshift("joseph""Jane"); console. log(name);

输出如下所示。

[" joseph ", Jane "," charlie "," john "]

6、encodeR0和 decodeR0的作用是什么?

encodeURI()用于将URL转换为十六进制编码。而 decodeURI()用于将编码的URL转换回正常URL。

7、为什么不建议在 JavaScript中使用 innerHTML?

通过 innerHTML修改内容,每次都会刷新,因此很慢。在 innerHTML中没有验证的机会,因此更容易在文档中插入错误代码,使网页不稳定。

8、如何在不支持 JavaScript的旧浏览器中隐藏 JavaScript代码?

在< script>标签之后的代码中添加“<!–”,不带引号。

在< /script>标签之前添加“//–>”,代码中没有引号。

旧浏览器现在将 JavaScript代码视为一个长的HTML注释,而支持 JavaScript的浏览器则将”<!-“和”//–>”作为一行注释。

9、在DOM操作中怎样创建、添加、移除、替换、插入和查找节点?

具体方法如下。

(1)通过以下代码创建新节点。

createDocument Fragment ()//创建一个D0M片段createElement ()//创建一个具体的元素createTextNode ()//创建一个文本节点

(2)通过以下代码添加、移除、替换、插入节点

appendchild()removechild()eplacechild ()insertBefore ()//并没有 insertAfter()(3)通过以下代码查找节点。getElementsByTagName ()//通过标签名称查找节点getElementsByName ()//通过元素的name属性的值查找节点(IE容错能力较强,会得到一个数//组,其中包括id等于name值的节点)getElementById(//通过元素Id查找节点,具有唯一性

10、如何实现浏览器内多个标签页之间的通信?

调用 localstorge、 cookie等数据存储通信方式

11、null和 undefined的区别是什么?

null是一个表示“无”的对象,转为数值时为0;undefined是一个表示“无”的原始值,转为数值时为NaN。

当声明的变量还未初始化时,变量的默认值为 undefined 。

null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。

undefined表示“缺少值”,即此处应该有一个值,但是还没有定义,典型用法是如下。

(1)如果变量声明了,但没有赋值,它就等于 undefined

(2)当调用函数时,如果没有提供应该提供的参数,该参数就等于 undefined。

(3)如果对象没有赋值,该属性的值为 undefined。

(4)当函数没有返回值时,默认返回 undefined。

null表示“没有对象”,即此处不应该有值,典型用法是如下。

(1)作为函数的参数,表示该函数的参数不是对象。

(2)作为对象原型链的终点。

12、new操作符的作用是什么?

作用如下:

(1)创建一个空对象。

(2)由this变量引用该对象

(3)该对象继承该函数的原型(更改原型链的指向)

(4)把属性和方法加入到this引用的对象中。

(5)新创建的对象由this引用,*后隐式地返回this,过程如下:

var obj ={};obj._ _ proto_ _ Base .prototype; Base .call(obj);

13、JavaScript延迟加载的方式有哪些?

包括 defer和 async、动态创建DOM(创建 script,插入DOM中,加载完毕后回调、按需异步载入 JavaScript。

14、call()和apply()的区别和作用是什么?

作用都是在函数执行的时候,动态改变函数的运行环境(执行上下文)。

call和 apply的*个参数都是改变运行环境的对象。

区别如下。

call从第二个参数开始,每一个参数会依次传递给调用函数;apply的第二个参数是数组,数组的每一个成员会依次传递给调用函数。

func, call(funcl, varl, var2, var3)

对应的 apply写法为:

func. apply (funcl, [varl, var2, var3])

15、哪些操作会造成内存泄漏?

内存泄漏指不再拥有或需要任何对象(数据)之后,它们仍然存在于内存中。

提示:垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为0(没有其他对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象占用的内存立即被回收。

如果 setTimeout的*个参数使用字符串而非函数,会引发内存泄漏闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)等会造内存泄漏。

16、列举E与 firefox的不同之处。

不同之处如下

(1)IE支持 currentStyle;Firefox使用 get ComputStyle。

(2)IE使用 inner Text;Firefox使用 textContent。

(3)在透明度滤镜方面,正使用 filter:alpha( opacity=num);Firefox使用-moz- opacity :num

(4)在事件方面,IE使用 attachEvent:Firefox使用 add Event Listener

(5)对于鼠标位置:IE使用 event. clientX;Firefox使用 event. pageX。

(6)IE使用 event. srcElement;Firefox使用 event. target

(7)要消除list的原点,IE中仅须使 margin:0即可达到*终效果;Firefox中需要设置margin:0、 padding:0和 list-style:none

(8)CSS圆角:IE7以下不支持圆角。

17、讲解一下 JavaScript对象的几种创建方式。

有以下创建方式:

(1) Object构造函数式。

(2)对象字面量式。

(3)工厂模式。

(4)安全工厂模式。

(5)构造函数模式。

(6)原型模式。

(7)混合构造函数和原型模式。

(8)动态原型模式。

(9)寄生构造函数模式。

(10)稳妥构造函数模式。

18、如何实现异步编程?

具体方法如下:

方法1,通过回调函数。优点是简单、容易理解和部署;缺点是不利于代码的阅读和维护,各个部分之间高度耦合( Coupling),流程混乱,而且每个任务只能指定一个回调函数。

方法2,通过事件监听,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以“去耦合”( Decoupling),有利于实现模块化;缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

方法3,采用发布/订阅方式。性质与“事件监听”类似,但是明显优于后者。

方法4,通过 Promise对象实现, Promise对象是 Commonjs工作组提出的一种规范,旨在为异步编程提供统一接口。它的思想是,每一个异步任务返回一个 Promise对象,该对象有一个then方法,允许指定回调函数。

19、请解释一下 JavaScript的同源策略。

同源策略是客户端脚本(尤其是 JavaScript)的重要安全度量标准。它*早出自Netscape Navigator2.0,目的是防止某个文档或脚本从多个不同源装载。

这里的同源策略指的是协议、域名、端口相同。同源策略是一种安全协议。指一段脚本只能读取来自同一来源的窗口和文档的属性。

20、为什么要有同源限制?

我们举例说明。比如一个黑客,他利用 Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名、密码登录时,他的页面就可以通过 Javascript读取到你表单上 Input中的内容,这样黑客就会轻松得到你的用户名和密码。

21、在 JavaScript中,为什么说函数是*类对象?

*类函数即 JavaScript中的函数。这通常意味着这些函数可以作为参数传递给其他函数,作为其他函数的值返回,分配给变量,也可以存储在数据结构中。

22、什么是事件?E与 Firefox的事件机制有什么区别?如何阻止冒泡?

事件是在网页中的某个操作(有的操作对应多个事件)例如,当单击一个按钮时,就会产生一个事件,它可以被 JavaScript侦测到,在事件处理机制上,正E支持事件冒泡;Firefox同时支持两种事件模型,也就是捕获型事件和冒泡型事件。

阻止方法是 ev.stop Propagation.注意旧版E中的方法 ev. cancelBubble=true.

23、函数声明与函数表达式的区别?

在 JavaScript中,在向执行环境中加载数据时,解析器对函数声明和函数表达式并非是一视同仁的。解析器会首先读取函数声明,并使它在执行任何代码之前可用(可以访问)。至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正解析和执行它。

24、如何删除一个 cookie?

为了删除 cookie,要修改 expires,代码如下。

document. cookie =’user=icketang;expires =’+ new Date(0)

25、编写一个方法,求一个字符串的长度(单位是字节)

假设一个英文字符占用一字节,一个中文字符占用两字节:

function GetBytes(str){ var len=str .length; var bytes= len forvar i-0:i<len1++){if (str. charcodeAt (i)>255) bytes++;}return bytes;}alert( GetBytes("hello 有课前端网!"));

26、对于元素, attribute和 property的区别是什么?

attribute是DOM元素在文档中作为HTML标签拥有的属性;property就是DOM元素在 JavaScript中作为对象拥有的属性。

对于HTML的标准属性来说, attribute和 property是同步的,会自动更新,但是对于自定义的属性来说,它们是不同步的。

27、解释延迟脚本在 JavaScript中的作用。

默认情况下,在页面加载期间,HTML代码的解析将暂停,直到脚本停止执行。

这意味着,如果服务器速度较慢或者脚本特别“沉重”,则会导致网页延迟。在使用Deferred时,脚本会延迟执行,直到HTML解析器运行。这缩短了网页的加载时间,并且它们的显示速度更快。

28、什么是闭包( closure)?

为了说明闭包,创建一个闭包。

function hello(){//函数执行完毕,变量仍然存在var num= 100;var showResult= function(){ alert (num);} num++;return showResult ;}var showResult= he1lo();showResult()//执行结果:弹出101

执行 hello()后, hello()闭包内部的变量会存在,而闭包内部函数的内部变量不会存在,使得 JavaScript的垃圾回收机制不会收回hello()占用的资源,因为hell()中内部函数的执行需要依赖 hello()中的变量。

29、如何判断一个对象是否属于某个类?

使用 instanceof关键字,判断一个对象是否是类的实例化对象;使用 constructor属性,判断一个对象是否是类的构造函数。

30、JavaScript中如何使用事件处理程序?

事件是由用户与页面的交互(例如单击链接或填写表单)导致的操作。需要个事件处理程序来保证所有事件的正确执行。事件处理程序是对象的额外属性。此属性包括事件的名称和事件发生时采取的操作。

31、在 JavaScript中有一个函数,执行直接对象查找时,它始终不会查找原型,这个函数是什么?

hasOwnProperty。

32、在 JavaScript中如何使用DOM?

DOM代表文档对象模型,并且负责文档中各种对象的相互交互。DOM是开发网页所必需的,其中包括诸如段落、链接等对象。可以操作这些对象,如添加或删除等。为此,DOM还需要向网页添加额外的功能。

33、documen.wrte和 innerHTML的区别是什么?

document.wite重绘整个页面;innerHTML可以重绘页面的一部分。

34、在 JavaScript中读取文件的方法是什么?

可以通过如下方式读取服务器中的文件内容。

function readAjaxEile(url) {//创建xhr var xhr =new XMLHttpRequest();/监听状态xhr. onreadystatechange=function(){//监听状态值是4if(xhr. readystate == 4 && xhr. status = = =200){console. log(xhr. responseText)}//打开请求xhr.open('GET', url, true)//发送数据xhr, send(null)}

可以通过如下方式读取本地计算机中的内容。

function readInputFile(id) { var file= document. getElementById(id). files[0];//实例化 FileReader var reader=new FileReader();//读取文件reader. readAsText (file)//监听返回reader, onload= function (data) { console. log (data, this .result)}}

35、如何分配对象属性?

将属性分配给对象的方式与赋值给变量的方式相同。例如,表单对象的操作值以下列方式分配给” submit”:document.form. action=” submit'”

36、请说几条书写 JavaScript语句的基本规范。

基本规范如下:

(1)不要在同一行声明多个变量。

(2)应使用==/!==来比较true/ false或者数值。

(3)使用对象字面量替代 new Array这种形式。

(4)不要使用全局函数。

(5) switch语句必须带有 default分支。

(6)函数不应该有时有返回值,有时没有返回值。

(7)for循环必须使用大括号括起来。

(8)if语句必须使用大括号括起来。

9)for-in循环中的变量应该使用war关键字明确限定的作用域,从而避免作用域污染。

37、eva的功能是什么?

它的功能是把对应的字符串解析成 Javascript代码并运行应该避免使用eval,它会造成程序不安全,非常影响性能(执行两次,一次解析成JavaScript语句,一次执行)

38、[“1,”2,”3”].map( parselnt)的执行结果是多少?

[1,NaN,NaN],因为 parseInt需要两个参数(val, radix),其中 radix表示解析时用的基数(进制);map传递了3个参数(item, index,aray),对应的radix不合法导致解析失败。

39、谈谈你对this对象的理解。

this是 JavaScript的一个关键字,随着函数使用场合的不同,this的值会发生变化。但是有一个总原则,即this指的是调用函数的那个对象一般情况下,this是全局对象 Global,可以作为方法调用

40、Web- garden和web-farm有什么不同?

web-garden和 web-farm都是网络托管系统。唯一的区别是 web-garden是在单个服务器中包含许多处理器的设置,而web-farm是使用多个服务器的较大设置。

41、说一下 document. write0的用法。

document. write()方法可以用在两个地方,页面载入过程中用实时脚本创建页面内容,以及用延时脚本创建本窗口或新窗口的内容document. write只能重绘整个页面, innerHTML可以重绘页面的一部分。

42、在 JavaScript中什么是类(伪)数组?如何将类(伪)数组转化为标准数组?

典型的类(伪)数组是函数的 argument参数,在调用 getElements By TagName和 document .childNodes方法时,它们返回的 NodeList对象都属于伪数组。可以使用Array .prototype. slice. call( fake Array)将数组转化为真正的Aray对象。

43、JavaScript中callee和 caller的作用是什么?

caller返回一个关于函数的引用,该函数调用了当前函数;callee返回正在执行的函数,也就是指定的 function对象的正文。

44、讲一下手写数组快速排序的步骤。

“快速排序”的思想很简单,整个排序过程只需要3步

(1)在数据集之中,选择一个元素作为“基准”( pivot)。

(2)将所有小于“基准”的元素,都移到“基准”的左边;将所有大于“基准”的元素,都移到“基准”的右边。

(3)对“基准”左边和右边的两个子集,不断重复第(1)步和第(2)步,直到所有子集只剩下一个元素为止。

45、如何统计字符串“ aaaabbbccccddfgh”中字母的个数或统计*多的字母数?

具体代码如下

var str =aaaabbbecccddfgh"; function dealstr(str){ var obj={};for (var i= 0;i< str length:i++){var v=str.charAt (i);if (obj[v] && obj [v].value === v){++obj[v]. count } else { obj[v] ={count:1, va⊥ue:v}}} return obj ;}var obj= dealstr(str);for (key in obj){ console. log (obj[key] .value +'=' obj[ key].count)}

46、写一个 function,清除字符串前后的空格(兼容所有浏览器)。

具体代码如下

function trim(str){if (str && typeof str === "string"){ return str.replace(/^\s+1\s+$/g,"");//去除前后空白符。

47、列出不同浏览器中关于 JavaScript兼容性的两个常见问题。

(1)事件绑定兼容性问题。

IE8以下的浏览器不支持用 add Event Listener来绑定事件,使用 attachement可以解决这个问题

(2) stopPropagation兼容性问题

IE8以下的浏览器不支持用 e .stopPropagation()来阻止事件传播,使用 e .return Value =false可以解决这个问题。

48、闭包的优缺点是什么?

优点是不产生全局变量,实现属性私有化缺点是闭包中的数据会常驻内存,在不用的时候需要删除,否则会导致内存溢出(内存泄漏)。

49、用 JavaScript实现一个数组合并的方法(要求去重)。

代码如下。

var arrl =['a']; var arr2 =['b', 'c'];var arr3=['c', ['d'], 'e', undefined, null];var concat =( function() {//去重合并arr1和arr2var _concat =function (arrl, arr2)for (var i =0, len= arr2.length;i< len;i++){~ arrl. indexOf (arr2[i])|| arrl. push(arr2[i])}}//返回数组去重合并方法return function(){ var result =[];for (var i=0, len= arguments .length;i< len:i++){ _concat (result, arguments [i])return result}})()

执行concat(arrl,ar2,ar3)后,会返回[‘a’,null, undefined,’e’,[‘d],’c’,’b’]。

50、说明正则表达式给所有string对象添加去除首尾空白符的方法(trim方法)。

代码如下。

prototype. trim= function(){return this .replace(/^\s+I\s+$/g," );};

51、说明用 JavaScript实现一个提取电话号码的方法。

代码如下

var str="12345678901 021-12345678 有课前端网 0418-1234567  13112345678"; var reg=/(1\d{0})|(0\d{2,3}\-\d{7,8})/g;alert(str.match(reg);

测试“12345678901 021-12345678有课前端网0418-1234567 13112345678”,得到的结果应该是:[12345678901,021-12345678,0418-1234567,13112345678]

52、JavaScript中常用的逻辑运算符有哪些?

“and”(&&)运算符、“or”(‖)运算符和”not”(!)运算符,它们可以在 JavaScript中使用。

53、什么是事件代理(事件委托)?

事件代理( Event Delegation),又称为事件委托,是 JavaScript中绑定事件的常用技巧。顾名思义,“事件代理”就是把原本需要绑定的事件委托给父元素,让父元素负責事件监听。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。

54、什么是 JavaScript?

JavaScript是客户端和服务器端的脚本语言,可以插入HTML页面中,并且是目前较热门的Web开发语言,同时, JavaScript也是面向对象的编程语言。

55、列举Java和 JavaScript的不同之处。

Java是一门十分完整、成熟的编程语言。相比之下, JavaScript是一个可以被引入HTML页面的编程语言。这两种语言并不完全相互依赖,而是针对不同的意图而设计的。Java是一种面向对象编程(OOP)或结构化编程语言,类似的语言有C++;而 JavaScript是客户端脚本语言,它称为非结构化编程。

56、JavaScript和ASP脚本相比,哪个更快?

JavaScript更快。JavaScript是一种客户端语言,因此它不需要Web服务器的协助就可以执行;ASP是服务器端语言,因此它总是比 JavaScript慢,值得注意的是, JavaScript现在也可用于服务器端语言( Node. js)

57、什么是负无穷大?

Infinity代表了超出 JavaScript处理范围的数值。也就是说, JavaScript无法处理的数值都是 Infinity.实践证明, JavaScript所能处理的*大值( Number. MAX VALUE)是17976931348623157e+308,超过该数则为正无穷大;而*小值( Number. MIN VALUE)

是5e-324,小于该数则为0.所以负无穷大代表的是小于- Number MAX VALUE的数字, JavaScript中对应静态变量 Number NEGATIVE INFINITY

58、如何将 JavaScript代码分解成几行?

M:在字符串语句中可以通过在*行末尾使用反斜杠“\”来完成,例如, document. write(”This is \a program”)。

如果不是在字符串语句中更改为新行,那么 JavaScript会忽略行中的断点下面的代码是完美的,但并不建议这样做,因为阻碍了调试。

var x=l, y=2,z=X+y;

59、什么是未声明和未定义的变量?

未声明的变量是程序中不存在且未声明的变量。如果程序尝试读取未声明变量的值,则会在运行时遇到错误。未定义的变量是在程序中声明但尚未给出任何值的变量如果程序尝试读取未定义变量的值,则返回未定义的值60.:如何编写可动态添加新元素的代码?

下面给出一段示例代码

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><tit1e>有课前端网—专业前端技术学习网</tit1e></head><body><p id="ickt">ickt</p><script type="text/javascript">function addNode (){ var p= document. createElement('p');var textNode document, createTextNode('有课前端网')p .appendchild(textNode);document. getElementById('ickt') .appendChild(p)}addNode ()</script></body></html>

61、什么是全局变量?这些变量如何声明?使用全局变量有哪些问题?

全局变量是整个代码中都可用的变量,也就是说,这些变量没有任何作用域var关键字用于声明局部变量,如果省略var关键字,则声明一个全局变量使用全局变量面临的问题是局部变量和全局变量名称的冲突。此外,很难调试和测试依赖于全局变量的代码。

62、解释 JavaScript中定时器的工作,并说明使用定时器的缺点。

定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码这通过使用函数 setTimeout、setInterval和 clearInterva来完成。

setTimeout( function, delay)函数用于启动在所属延迟之后调用特定功能的定时器。

setInterval( function,dlay)函数用于在提到的延迟中重复执行给定的功能,只有在取消时才停止。

clearInterval(id)函数指示定时器停止定时器在一个线程内运行,因此事件可能需要排队等待执行。

63、ViewState和 SessionState有什么区别?

View State特定于会话中的页面;SessionState特定于可在Web应用程序中的所有页面上访问的用户特定数据。

64、什么是===运算符?

===称为严格等式运算符,当两个操作数具有相同的值和类型时,该运算符返回true。

65、说明如何使用 JavaScript提交表单。

要使用 JavaScript提交表单,可以使用以下代码。

document .form [0] .submit();

66、元素的样式/类如何改变?

可以通过以下方式改变元素的样式。

document. getElementById("myText").style. fontsize ="20";

可以通过以下方式改变元素的类。

document. getElementById("myText ").className ="anyclass";

67、JavaScript中的循环结构都有哪些?

for、 while、do.… while、 for in、 for of(ES6新增的)

68、如何在 JavaScript中将base字符串转换为 integer?

parselnt()函数解析一个字符串参数,并返回一个指定基数的整数。parselnt()将要转换的字符串作为其*个参数,第二个参数是给定字符串的转换进制基数。

为了将4F(基数16)转换为整数,可以使用代码 parrent(”4F”,16)。

69、说明“==”和“===”的区别。

“==”仅检查值相等性,而“===”用于更严格的等式判定。如果两个变量的值或类型不同,则后者返回 false。

70、3+2+“7”的结果是什么?

由于3和2是整数,它们将直接相加,同时由于“7”是一个字符串,将会被直连接,因此结果将是57。

71、如何检测客户端机器上的操作系统?

为了检测客户端机器上的操作系统,应使用 navigator.app Version字符串(属性)。

72、JavaScript中的null表示什么?

null用于表示无值或无对象。它意味着没有对象或空字符串,没有有效的布尔没有数值和数组对象

73、delete操作符的功能是什么?

delete操作符用于删除对象中的某个属性,但不能删除变量、函数等。

74、JavaScript中有哪些类型的弹出框?

ua;alert、 confirm和 prompt。

75、void(0)的作用是什么?

void操作符使表达式的运算结果返回 undefined。

void(0)用于防止页面刷新,并在调用时传递参数“0”。

void(0)用于调用另一种方法而不刷新页面。

76、如何强制页面加载 JavaScript中的其他页面?

必须插入以下代码才能达到预期效果。

<script language="JavaScript"  type="text/javascript"><!--location.href="http://newhost/newpath/newfile.html";//--></script>

77、转义字符是用来做什么的?

当使用特殊字符(如单引号、双引号、撇号和&符号)时,将使用转义字符(反斜杠)。在字符前放置反斜杠,使其显示。

下面给出两个示例。

document. write"I m a "good"boy "document. write"I m a\"good\"boy"

78、什么是 JavaScript cookie?

cookie是存储在访问者计算机中的变量。每当一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。可以使用 JavaScript来创建和获取 cookie的值。

79、解释 JavaScript中的pop()方法。

pop()方法与shift()方法类似,但不同之处在于shift()方法在数组的开头工作。此外,pop()方法将*后一个元素从给定的数组中取出并返回,然后改变被调用的数组例如:

var colors = ["red","blue","green"]; colors. pop ();// colors :["red","blue"]
80、在 JavaScript中使用 innerHTML的缺点是什么?
缺点如下:
(1)内容随处可见
(2)不能像“追加到 innerHTML”一样使用。
(3)即使使用+=,如” innerHTML= innerhTML+’htm'”,旧的内容仍然会被HTML替换。

(4)整个 innerHTML内容被重新解析并构建成元素,因此它的速度要慢得多。

(5) innerHTML不提供验证,因此可能会在文档中插入具有破坏性的HTML并将其中断。

81、break和 continue语句的作用是什么?

break语句从当前循环中退出;continue语句继续下一个循环语句。

82、在 JavaScript中, datatypes的两个基本组是什么?

两个基本组是原始类型和引用类型。

原始类型包括数字和布尔类型。引用类型包括更复杂的类型,如字符串和日期。

83、如何创建通用对象?

通用对象可以通过以下代码创建。

var o= new Object ()。

84、typeof是用来做什么的?

typeof是一个运算符,用于返回变量类型的字符串描述。

85、哪些关键字用于处理异常?

try...catch...finally用于处理 JavaScript中的异常。try{执行代码}catch(exp){ 抛出错误提示信息}finally {无论try/catch的结果如何都会执行。}

86、JavaScript中不同类型的错误有几种?

有3种类型的错误。

Load time errors,该错误发生于加载网页时,例如出现语法错误等状况,称为加载时间错误,并且会动态生成错误。

Run time errors,由于在HTML语言中滥用命令而导致的错误。

Logical errors,这是由于在具有不同操作的函数上执行了错误逻辑而发生的错误。

87、在 JavaScript中,push方法的作用是什么?

push方法用于将一个或多个元素添加或附加到数组的末尾。使用这种方法,可通过传递多个参数来附加多个元素。

88、在 JavaScript中, unshift方法的作用是什么?

unshift方法就像在数组开头工作的push方法。该方法用于将一个或多个元素添加到数组的开头。

89、如何为对象添加属性?

为对象添加属性有两种常用语法。

中括号语法,比如obj[” class”]=12。

点语法,比如 obj. class=12。

90、获得 CheckBox状态的方式是什么?

alert( document getElement Byld(’checkbox1’) .checked;

如果 CheckBox选中,此警告将返回TRUE。

91、解释一下 window. onload和 onDocumentReady。

在载入页面的所有信息之前,不运行 window. onload。这导致在执行任何代码之前会出现延迟。

window.onDocumentReady在加载DOM之后加载代码。这允许代码更早地执行(早于 window. onload)。

92、如何理解 JavaScript中的闭包?

闭包就是能够读取其他函数内部变量的函数。

闭包的用途有两个,一是可以读取函数内部的变量,二是让这些变量的值始终保持在内存中。

93、如何把一个值附加到数组中?

可以在数组末尾处添加成员arr[ arr length]= value;或者调用push方法 arr.push(value)。

94、解释一下for-in循环。

for-in循环用于循环对象的属性。

for-in循环的语法如下。

for (var iable name in object){}

在每次循环中,来自对象的一个属性与变量名相关联,循环继续,直到对象的所有属性都被遍历。

95、描述一下 JavaScript中的匿名函数。

被声明为没有任何命名标识符的函数称为匿名函数。一般来说,匿名函数在声明后无法访问。

匿名函数声明示例如下。

var anon=function(){alert('I am anonymous' );anon();

96、和DOM事件流的区别是什么?

区别如下。

(1)执行顺序不一样

(2)参数不一样。

(3)事件名称是否加on不一样。

(4)this指向问题不一样。

97、阐述一下事件冒泡。

Java Script允许DOM元素嵌套在一起。在这种情况下,如果单击子级的处理程序,父级的处理程序也将执行同样的工作。

98、JavaScript里函数参数 arguments是数组吗?

在函数代码中,使用特殊对象 arguments,开发者无须明确指出参数名,使用下标就可以访问相应的参数。

arguments虽然有数组的性质,但其并非真正的数组。它只是一个类数组对象,并没有数组的方法,不能像真正的数组那样调用 .join()、, .concat()、.pop()等方法。

99、什么是构造函数?它与普通函数有什么区别?

构造函数是一种特殊的方法,主要用来创建对象时初始化对象,经常与new运算符一起使用,创建对象的语句中构造函数的名称必须与类名完全相同。

与普通函数相比,区别如下

(1)构造函数只能由new关键字调用

(2)构造函数可以创建实例化对象

(3)构造函数是类的标志。

100、请解释一下 JavaScript和CSS阻塞。

JavaScript的阻塞特性是所有浏览器在下载 JavaScript代码的时候,会阻止其他一切活动,比如其他资源的下载,内容的呈现等,直到 JavaScript代码下载、解析、执行完毕后才开始继续并行下载其他资源并渲染内容。

为了提高用户体验,新一代浏览器都支持并行下载 JavaScript代码,但是 JavaScript代码的下载仍然会阻塞其他资源的下载(例如图片、CSS文件等)。

为了防止 JavaScript修改DOM树,浏览器需要重新构建DOM树,所以就会阻塞其他资源的下载和渲染。

嵌入的 JavaScript代码会阻塞所有内容的呈现,而外部 JavaScript代码只会阻塞其后内容的显示,两种方式都会阻塞其后资源的下载。也就是说,外部脚本不会阻塞外部脚本的加载,但会阻塞外部脚本的执行。

CSS本来是可以并行加载的,但是当CSS后面跟着嵌入的 JavaScript代码的时候,该CSS就会阻塞后面资源的下载。

而当把嵌入的 JavaScript代码放到CSS前面时,就不会出现阻塞的情况了(在IE6下CSS都会阻塞加载)。

根本原因是因为浏览器会维持HTML中CSS和 JavaScript代码的顺序,样式表必须在嵌入的 JavaScript代码执行前先加载、解析完。而嵌入的 JavaScript代码会阻塞后面的资源加载,所以就会出现CSS阻塞资源加载的情况。

本文完~

java大文件(百M以上)的上传下载功能

javaweb上传文件

上传文件的jsp中的部分

上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求

1.通过form表单向后端发送请求

<form id=”postForm” action=”${pageContext.request.contextPath}/UploadServlet” method=”post” enctype=”multipart/form-data”>

<div class=”bbxx wrap”>

<inputtype=”text” id=”side-profile-name” name=”username” class=”form-control”>

<inputtype=”file” id=”example-file-input” name=”avatar”>

<button type=”submit” class=”btn btn-effect-ripple btn-primary”>Save</button>

</div>

</form>

改进后的代码不需要form标签,直接由控件来实现。开发人员只需要关注业务逻辑即可。JS中已经帮我们封闭好了

this.post_file = function ()

{

$.each(this.ui.btn, function (i, n) { n.hide();});

this.ui.btn.stop.show();

this.State = this.Config.state.Posting;//

this.app.postFile({ id: this.fileSvr.id, pathLoc: this.fileSvr.pathLoc, pathSvr:this.fileSvr.pathSvr,lenSvr: this.fileSvr.lenSvr, fields: this.fields });

};

通过监控工具可以看到控件提交的数据,非常的清晰,调试也非常的简单。

2.通过ajax向后端发送请求

$.ajax({

url : “${pageContext.request.contextPath}/UploadServlet”,

type : “POST”,

data : $( ‘#postForm’).serialize(),

success : function(data) {

$( ‘#serverResponse’).html(data);

},

error : function(data) {

$( ‘#serverResponse’).html(data.status + ” : ” + data.statusText + ” : ” + data.responseText);

}

});

ajax分为两部分,一部分是初始化,文件在上传前通过AJAX请求通知服务端进行初始化操作

this.md5_complete = function (json)

{

this.fileSvr.md5 = json.md5;

this.ui.msg.text(“MD5计算完毕,开始连接服务器…”);

this.event.md5Complete(this, json.md5);//biz event

 

var loc_path = encodeURIComponent(this.fileSvr.pathLoc);

var loc_len = this.fileSvr.lenLoc;

var loc_size = this.fileSvr.sizeLoc;

var param = jQuery.extend({}, this.fields, this.Config.bizData, { md5: json.md5, id: this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time: new Date().getTime() });

 

$.ajax({

type: “GET”

, dataType: ‘jsonp’

, jsonp: “callback” //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名

, url: this.Config[“UrlCreate”]

, data: param

, success: function (sv)

{

_this.svr_create(sv);

}

, error: function (req, txt, err)

{

_this.Manager.RemoveQueuePost(_this.fileSvr.id);

alert(“向服务器发送MD5信息错误!” + req.responseText);

_this.ui.msg.text(“向服务器发送MD5信息错误”);

_this.ui.btn.cancel.show();

_this.ui.btn.stop.hide();

}

, complete: function (req, sta) { req = null; }

});

};

 

在文件上传完后向服务器发送通知

this.post_complete = function (json)

{

this.fileSvr.perSvr = “100%”;

this.fileSvr.complete = true;

$.each(this.ui.btn, function (i, n)

{

n.hide();

});

this.ui.process.css(“width”, “100%”);

this.ui.percent.text(“(100%)”);

this.ui.msg.text(“上传完成”);

this.Manager.arrFilesComplete.push(this);

this.State = this.Config.state.Complete;

//从上传列表中删除

this.Manager.RemoveQueuePost(this.fileSvr.id);

//从未上传列表中删除

this.Manager.RemoveQueueWait(this.fileSvr.id);

 

var param = { md5: this.fileSvr.md5, uid: this.uid, id: this.fileSvr.id, time: new Date().getTime() };

 

$.ajax({

type: “GET”

, dataType: ‘jsonp’

, jsonp: “callback” //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名

, url: _this.Config[“UrlComplete”]

, data: param

, success: function (msg)

{

_this.event.fileComplete(_this);//触发事件

_this.post_next();

}

, error: function (req, txt, err) { alert(“文件-向服务器发送Complete信息错误!” + req.responseText); }

, complete: function (req, sta) { req = null; }

});

};

 

这里需要处理一个MD5秒传的逻辑,当服务器存在相同文件时,不需要用户再上传,而是直接通知用户秒传

this.post_complete_quick = function ()

{

this.fileSvr.perSvr = “100%”;

this.fileSvr.complete = true;

this.ui.btn.stop.hide();

this.ui.process.css(“width”, “100%”);

this.ui.percent.text(“(100%)”);

this.ui.msg.text(“服务器存在相同文件,快速上传成功。”);

this.Manager.arrFilesComplete.push(this);

this.State = this.Config.state.Complete;

//从上传列表中删除

this.Manager.RemoveQueuePost(this.fileSvr.id);

//从未上传列表中删除

this.Manager.RemoveQueueWait(this.fileSvr.id);

//添加到文件列表

this.post_next();

this.event.fileComplete(this);//触发事件

};

这里可以看到秒传的逻辑是非常 简单的,并不是特别的复杂。

var form = new FormData();

form.append(“username”,”zxj”);

form.append(“avatar”,file);

//var form = new FormData($(“#postForm”)[0]);

$.ajax({

url:”${pageContext.request.contextPath}/UploadServlet”,

type:”post”,

data:form,

processData:false,

contentType:false,

success:function(data){

 

console.log(data);

}

});

java部分

文件初始化的逻辑,主要代码如下

FileInf fileSvr= new FileInf();

fileSvr.id = id;

fileSvr.fdChild = false;

fileSvr.uid = Integer.parseInt(uid);

fileSvr.nameLoc = PathTool.getName(pathLoc);

fileSvr.pathLoc = pathLoc;

fileSvr.lenLoc = Long.parseLong(lenLoc);

fileSvr.sizeLoc = sizeLoc;

fileSvr.deleted = false;

fileSvr.md5 = md5;

fileSvr.nameSvr = fileSvr.nameLoc;

 

//所有单个文件均以uuid/file方式存储

PathBuilderUuid pb = new PathBuilderUuid();

fileSvr.pathSvr = pb.genFile(fileSvr.uid,fileSvr);

fileSvr.pathSvr = fileSvr.pathSvr.replace(“\\”,”/”);

 

DBConfig cfg = new DBConfig();

DBFile db = cfg.db();

FileInf fileExist = new FileInf();

 

boolean exist = db.exist_file(md5,fileExist);

//数据库已存在相同文件,且有上传进度,则直接使用此信息

if(exist && fileExist.lenSvr > 1)

{

fileSvr.nameSvr             = fileExist.nameSvr;

fileSvr.pathSvr        = fileExist.pathSvr;

fileSvr.perSvr              = fileExist.perSvr;

fileSvr.lenSvr              = fileExist.lenSvr;

fileSvr.complete       = fileExist.complete;

db.Add(fileSvr);

 

//触发事件

up6_biz_event.file_create_same(fileSvr);

}//此文件不存在

else

{

db.Add(fileSvr);

//触发事件

up6_biz_event.file_create(fileSvr);

 

FileBlockWriter fr = new FileBlockWriter();

fr.CreateFile(fileSvr.pathSvr,fileSvr.lenLoc);

}

接收文件块数据,在这个逻辑中我们接收文件块数据。控件对数据进行了优化,可以方便调试。如果用监控工具可以看到控件提交的数据。

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload upload = new ServletFileUpload(factory);

List files = null;

try

{

files = upload.parseRequest(request);

}

catch (FileUploadException e)

{// 解析文件数据错误

out.println(“read file data error:” + e.toString());

return;

 

}

 

FileItem rangeFile = null;

// 得到所有上传的文件

Iterator fileItr = files.iterator();

// 循环处理所有文件

while (fileItr.hasNext())

{

// 得到当前文件

rangeFile = (FileItem) fileItr.next();

if(StringUtils.equals( rangeFile.getFieldName(),”pathSvr”))

{

pathSvr = rangeFile.getString();

pathSvr = PathTool.url_decode(pathSvr);

}

}

 

boolean verify = false;

String msg = “”;

String md5Svr = “”;

long blockSizeSvr = rangeFile.getSize();

if(!StringUtils.isBlank(blockMd5))

{

md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());

}

 

verify = Integer.parseInt(blockSize) == blockSizeSvr;

if(!verify)

{

msg = “block size error sizeSvr:” + blockSizeSvr + “sizeLoc:” + blockSize;

}

 

if(verify && !StringUtils.isBlank(blockMd5))

{

verify = md5Svr.equals(blockMd5);

if(!verify) msg = “block md5 error”;

}

 

if(verify)

{

//保存文件块数据

FileBlockWriter res = new FileBlockWriter();

//仅*块创建

if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));

res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));

 

JSONObject o = new JSONObject();

o.put(“msg”, “ok”);

o.put(“md5”, md5Svr);

o.put(“offset”, blockOffset);//基于文件的块偏移位置

msg = o.toString();

}

rangeFile.delete();

out.write(msg);

 

注:

1. 上面的java部分的代码可以直接使用,只需要将上传的图片路径及收集数据并将数据写入到数据库即可

2. 上面上传文件使用到了字节流,其实还可以使用别的流,这个需要读者自己在下面完善测试

3. BeanUtils是一个工具 便于将实体对应的属性赋给实体

4. 上传文件不能使用 request.getParameter(“”)获取参数了,而是直接将request解析,通过判断每一项是文件还是非文件,然后进行相应的操作(文件的话就是用流来读取,非文件的话,暂时保存到一个map中。)

深入理解JavaScript系列:设计模式之构造函数模式

介绍

构造函数大家都很熟悉了,不过如果你是新手,还是有必要来了解一下什么叫构造函数的。构造函数用于创建特定类型的对象——不仅声明了使用的对象,构造函数还可以接受参数以便*次创建对象的时候设置对象的成员值。你可以自定义自己的构造函数,然后在里面声明自定义类型对象的属性或方法。

基本用法

在JavaScript里,构造函数通常是认为用来实现实例的,JavaScript没有类的概念,但是有特殊的构造函数。通过new关键字来调用定义的否早函数,你可以告诉JavaScript你要创建一个新对象并且新对象的成员声明都是构造函数里定义的。在构造函数内部,this关键字引用的是新创建的对象。基本用法如下:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= function () {
return this.model + "走了" + this.miles + "公里";
    };
}

var tom= new Car("大叔", 2009, 20000);
var dudu= new Car("Dudu", 2010, 5000);

console.log(tom.output());
console.log(dudu.output());

上面的例子是个非常简单的构造函数模式,但是有点小问题。首先是使用继承很麻烦了,其次output()在每次创建对象的时候都重新定义了,*好的方法是让所有Car类型的实例都共享这个output()方法,这样如果有大批量的实例的话,就会节约很多内存。

解决这个问题,我们可以使用如下方式:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.output= formatCar;
}

function formatCar() {
return this.model + "走了" + this.miles + "公里";
}

这个方式虽然可用,但是我们有如下更好的方式。

构造函数与原型

JavaScript里函数有个原型属性叫prototype,当调用构造函数创建对象的时候,所有该构造函数原型的属性在新创建对象上都可用。按照这样,多个Car对象实例可以共享同一个原型,我们再扩展一下上例的代码:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
}

/*
注意:这里我们使用了Object.prototype.方法名,而不是Object.prototype
主要是用来避免重写定义原型prototype对象
*/
Car.prototype.output= function () {
return this.model + "走了" + this.miles + "公里";
};

var tom = new Car("大叔", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);

console.log(tom.output());
console.log(dudu.output());

这里,output()单实例可以在所有Car对象实例里共享使用。

另外:我们推荐构造函数以大写字母开头,以便区分普通的函数。

只能用new吗?

上面的例子对函数car都是用new来创建对象的,只有这一种方式么?其实还有别的方式,我们列举两种:

function Car(model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
// 自定义一个output输出内容
    this.output = function () {
return this.model + "走了" + this.miles + "公里";
    }
}

//方法1:作为函数调用
Car("大叔", 2009, 20000);  //添加到window对象上
console.log(window.output());

//方法2:在另外一个对象的作用域内调用
var o = new Object();
Car.call(o, "Dudu", 2010, 5000);
console.log(o.output());

该代码的方法1有点特殊,如果不适用new直接调用函数的话,this指向的是全局对象window,我们来验证一下:

//作为函数调用
var tom = Car("大叔", 2009, 20000);
console.log(typeof tom); // "undefined"
console.log(window.output()); // "大叔走了20000公里"

这时候对象tom是undefined,而window.output()会正确输出结果,而如果使用new关键字则没有这个问题,验证如下:

//使用new 关键字
var tom = new Car("大叔", 2009, 20000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"

强制使用new

上述的例子展示了不使用new的问题,那么我们有没有办法让构造函数强制使用new关键字呢,答案是肯定的,上代码:

function Car(model, year, miles) {
if (!(this instanceof Car)) {
return new Car(model, year, miles);
    }
this.model = model;
this.year = year;
this.miles = miles;
this.output = function () {
return this.model + "走了" + this.miles + "公里";
    }
}

var tom = new Car("大叔", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000);

console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"
console.log(typeof dudu); // "object"
console.log(dudu.output()); // "Dudu走了5000公里"

通过判断this的instanceof是不是Car来决定返回new Car还是继续执行代码,如果使用的是new关键字,则(this instanceof Car)为真,会继续执行下面的参数赋值,如果没有用new,(this instanceof Car)就为假,就会重新new一个实例返回。

原始包装函数

JavaScript里有3中原始包装函数:number, string, boolean,有时候两种都用:

// 使用原始包装函数
var s = new String("my string");
var n = new Number(101);
var b = new Boolean(true);


// 推荐这种
var s = "my string";
var n = 101;
var b = true;

推荐,只有在想保留数值状态的时候使用这些包装函数,关于区别可以参考下面的代码:

// 原始string
var greet = "Hello there";
// 使用split()方法分割
greet.split(' ')[0]; // "Hello"
// 给原始类型添加新属性不会报错
greet.smile = true;
// 单没法获取这个值(18章ECMAScript实现里我们讲了为什么)
console.log(typeof greet.smile); // "undefined"

// 原始string
var greet = new String("Hello there");
// 使用split()方法分割
greet.split(' ')[0]; // "Hello"
// 给包装函数类型添加新属性不会报错
greet.smile = true;
// 可以正常访问新属性
console.log(typeof greet.smile); // "boolean"

总结

本章主要讲解了构造函数模式的使用方法、调用方法以及new关键字的区别,希望大家在使用的时候有所注意。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速