javascript this 经典面试题
|
|
预解析之后
|
|
可以在控制台输出看下数据结构
|
|
看下面的求值过程
|
|
————————————- = 运算符面试题
|
|
keep Moving
|
|
预解析之后
|
|
可以在控制台输出看下数据结构
|
|
看下面的求值过程
|
|
————————————- = 运算符面试题
|
|
利用css sprites将网站用到的图片合并成一张图片,通过background-position
、width
、height
控制背景图位置来使用某一个图标,这种方式可以将多个图片请求缩减为一次,生成css sprites的工具也很多,grunt和gulp中都有相关的插件,CssGaga也不错。
和精灵图一样,合并css和js文件也是减少HTTP请求很重要的方式,对css文件的合并目前来说没有什么争议,但是对于当前js模块化盛行,将所有js文件合并成一个文件,仿佛是一种倒退。正确的方式是遵守编译型语言的模式,保持js的模块化,在生成过程中只对初始请求用到的js文件生成目标文件。
HTTP请求时间另一个影响因素是你与网站web服务器所处的距离,显然距离越远,请求所需的时间也越久,通过CDN可以大大改善这一点。
CDN是分布在多个不同地理位置的web服务器,用于更加有效的向用户发布内容。CDN最主要的功能是给终端用户存放静态文件,另外也提供下载、安全服务等功能。
CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
浏览器通过使用缓存可以避免每次都进行重复的请求,HTTP 1.0和HTTP1.1分别有不同的缓存实现方式,Expires
(1.0)和Cache-control
(1.1)。Web服务器通过expires告诉客户端在指定的时间内,都使用该文件的缓存副本,不再向服务端重复发出请求,例如:
|
|
这个设置意味着截止到2016年12月1日,都可以使用该缓存副本,无需再发出请求。
Expires这种通过截止日期的方式,存在一个限制:要求客户端和服务端时钟严格同步,而HTTP 1.1引入的Cache-Control通过指定一个以秒为单位的时间指定缓存日期,则不存该限制,例如:
|
|
这个设置意味缓存时间为一年,推荐使用Cache-Control,但是在支持HTTP 1.1的情况下,另外要注意的一点:Cache-Control和Expire同时存在时,Cache-Control具有更高的优先级。
使用Expire/Cache-Control可以避免第二次访问时,使用本地缓存避免重复HTTP请求,提高网站速度。然而,在用户点击了浏览器刷新或者在expire已过期的情况下,仍然会向服务端发出HTTP GET请求,而此时如果该文件并没有发生变化,服务端不会返回整个文件而是会返回304 Not Modified状态码。
服务端判断该文件是否发生变化的依据有两个:Last-Modified(最新修改日期)和ETag(实体标签);
ETag
(Entity Tags)是在HTTP 1.1引入的,与Last-Modified同时存在时要有更高的优先级。服务端通过对比客户端发来的ETag(If-None-Match)和当前ETag,若相同返回304 Not Modifed,否则返回整个文件以及200 OK。
ETag存在一个问题:当浏览器向一个服务器发送GET请求原始组件,之后又向另一台服务器请求该组件时,ETag是不匹配的,当然,如果你的网站寄宿在一台服务器上不存在这个问题,而现在很多网站使用多台服务器,ETag的存在就大大降低验证有效性的成功率。
存在这个问题是时的解决办法是对ETag进行配置,移除服务器innode值只保留修改时间戳和大小作为ETag值,或者直接移除ETag,使用Last-Modified
来验证文件有效性。
通过对HTTP传输的文件进行压缩减小HTTP请求的大小,提高请求速度,GZIP是目前最常用也是最有效的压缩方式。
然而,并非所有的资源文件都需要压缩,压缩的成本包括服务端需要花费CPU周期进行压缩,而客户端也需要对压缩文件进行解压缩,必须结合自己网站进行权衡。现在绝大多数网站都对其HTML文档进行压缩,部分网站选择对js、css进行压缩,几乎没有网站对图片、PDF等文件进行GZIP压缩,原因在于这些文件是已经被压缩过的,采用HTTP压缩已经被过压缩的东西并不能使它更小。事实上,添加标头,压缩字典,并校验响应体实际上使它变得更大,而且还浪费了CPU。
如何对网站开启GZIP,需要在所使用的web服务器(IIS、Nginx、Apache等)中进行设置。
将CSS文件放在首部和放在尾部,并不影响HTTP请求,因此从请求时间上来讲是一致的,然而从用户体验的角度,将CSS文件放在首部,会获得更好的用户体验。
原因在于浏览器是从上到下依次解析html文档,将CSS文件置于头部,页面会首先对CSS文件发出请求,随后加载DOM树并对其进行渲染,页面会逐步呈现在用户面前。
而与之相反,如果将CSS文件放置在尾部,页面加载完整DOM之后请求CSS文件,然后对整个DOM树渲染并呈现给用户,从用户的角度,在css文件没有请求完成之前,整个页面是出于白屏
状态的,白屏
是浏览器的一种行为,David Hyatt
对其的解释是这样的
在样式树没有完全加载之前,渲染dom树就是一种浪费,因为在样式树加载完成之后会再次渲染,出现FOUC(无样式内容闪烁)问题。
另外要注意的一点,使用link
而不是@import
引入css样式表,使用@import
引入的样式即使写在首部,也会在文档最后加载。
HTTP请求是并行的,不同浏览器并行下载的数目也不一样(2、4、或者8个),并行下载提高了HTTP请求的速度。而将JS文件放在首部,不仅会阻塞后面文件的下载而且会阻塞页面的渲染。
为什么会这样呢?原因有两个:
所以,最好的方式是讲js文件放置在尾部,等页面所有可视化组件加载完成之后再进行请求,提高用户体验。7
:判断图片位置距离页面顶部的距离,先不加载图片,当用户滚动到该位置的时候将图片的src属性赋值为实际值,data-src可以先缓存图片的真实路径,方便取出;
jQuery中筛选的总结:
1 查找子代 children( ),如果不加选择器,那么将选择所有的子代元素,可以加一个选择器进行筛选;注意仅仅匹配子代元素,不匹配后代(子代的子代);
查找所有后代 find( “ selector” ),可以选择所有的后代元素,包括子代的子代;
2 查找同辈元素:next() prev( ) 查找当前匹配到所有的对象的紧邻的后(前)一个元素;nextAll( ) prevAll( ),查找当前匹配对象的所有的对象的后面(前面)的所有元素;
3 查找匹配元素:first( ) last( ) ,查找匹配元素的第一个或者最后一个元素;
|
|
define ([ module1,module2····] ,callback) 中的module路径依赖
require([ module1,module2····],callback) 中的module路径依赖
二者的路径依赖如何?
目录如下
|
|
index.html
|
|
main.js
|
|
test.js
|
|
改变下目录结构
|
|
main.js 设置baseUrl
|
|
|
|
test.js 依赖模块路径以js/jq为准
|
|
scheme:host : port / path 即path根目录
myvirtual 是我的一个虚拟主机
|
|
main.js
|
|
test.js
|
|
|
|
index.html
|
|
main.js
|
|
test.js
|
|
module1.js
|
|
myvirtual2 / innervirtual2.js
|
|
6.1 如果直接通过路径获取包,如 2,3部分,文件后缀js可以省略
6.2 如果直接通过绝对路径获取包,如4部分,文件后缀js不能省略
6.3 如果设置require.config paths 设置包的路径,文件后缀js可以省略
在不同的分支上的内容是不一样的,切换到不同分支,工作区的文件内容也是不一样的
在分支合并之后可以选择将被合并的分支删除
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而
fast forward`合并就看不出来曾经做过合并
和远程仓库进行对接
merge之后可以删除分支,不删除也可以
当从远程仓库克隆的时候,仅仅克隆的是master分支,如果想要远程其他分支上的数据,比如master2分支
写在前面:有兴趣的还是可以阅读下httpd.conf以及httpd-vhosts.conf 文件里面的注释,方便理解;
下载wamp软件,安装完毕之后,启动apache服务器,在浏览器URL地址栏输入127.0.0.1或者localhost便可以进入apache主页(此时服务器默认的访问路径是(D是我安装在D盘) D/wamp/www/ 文件夹下面的index开头的文件,)
1.1 配置服务器访问路径
找到wamp —>bin —>apache 目录下面的 httpd.conf 修改默认访问路径,将 D/wamp/www/ 比如修改为 F:/mywork/
httpd.conf 中 DocumentRoot 可以修改默认访问的路径 F:/mywork/
httpd.conf 中 Directory 也要修改默认路径F:/web/
如果该路径F:/mywork/ 里面有index.html index.php 等以index命名的文件,会直接打开该文件,如果没有则进入F:/mywork/该目录
为什么会默认打开index开头的文件呢?在httpd.conf文件中,如下代码设置了默认打开目录下面的文件名字
DirectoryIndex决定打开虚拟主机的时候,默认打开的文件名称
|
|
|
|
1.2 配置服务器通过域名访问 虚拟主机
httpd.conf 文件中找到 # Virtual hosts 打开这行代码下面一行的 # 号
|
|
当我们打开虚拟主机之后,重启apache服务,在通过localhost或者127.0.0.1已经无法进入 F:/mywork/目录,需要重新配置wamp —>bin —>apache—>extra—>httpd-vhosts.conf文件
|
|
如下配置,我设置了三个主机,分别是mainVirtual myVirtual1 myVirtual2 对应不同的路径,但是都是F:/web/或者F:/web/的子目录,然后通过 ServerName ServerAlias设置的对应值,在浏览器的URL地址栏就可以访问了
1.2.1 设置host文件 C:\Windows\System32\drivers\etc 下面的host文件,我们在这里配置的域名,如果在URL地址栏输入该域名,我们就可以访问这个本机虚拟主机;
|
|
1.2.2 设置wamp —>bin —>apache—>extra—>httpd-vhosts.conf文件
|
|
1.2.3 这个时候我们通过www.mainVirtual.com www.myVirtual1.com www.myVirtual2.com就可以访问我们对应的主机咯(每个路径对应的目录要事先创建好)
假如 我在之前搭建的www.myVirtual1.com域下,也就是F:/web/myVirtual1文件夹下面有一个文件 test1.php
www.myVirtual2.com这个域内的文件想访问www.myVirtual1.com下面的test1.php文件
URL(Uniform Resource Locator) 地址用于描述一个网络上的资源, 基本格式如下
|
|
scheme host port三者有一个不一样就发生了跨域,如何解决跨域?
2.1 Access-Control-Allow-Origin:域名 表示设置允许哪个域名进行访问
header(“Access-Control-Allow-Origin: http://www.myvirtual2.com“) 通过对访问的跨域资源设置响应头,允许某个指定的域名来访问该文件;
|
|
这个是虚拟主机2 里面的请求文件
|
|
2.2 通过script标签 src属性
|
|
|
|
2.3 jQuery.ajax通过jsonp来进行跨域请求,本质上使用script标签发送请求,获取到的数据作为javascript代码直接执行
|
|
|
|
2.4 通过反向代理进行跨域访问
反向代理作用1:减轻源服务器负载 2:保障源服务器安全 3:对源服务器进行负载均衡(Load Balance)。通过在服务器端设置代理服务,可以进行跨域访问
打开httpd-conf文件,打开以下两行代码中的#号
|
|
我们在新建两个虚拟主机
|
|
在F:/web/5myvirtual5 下面有一个文件 01proxy.html
|
|
在F:/web/4myvirtual4 下有一个文件 01proxy.php
|
|
2.5 通过document.domain 设置同一主域不同子域中的页面相同的主域名,来允许不同子域之间进行访问
2.6 通过HTML5postMessage方法进行跨域操作,参见我的博客HTML5-postMessage
2.7 绕开浏览器,直接通过服务器端发送请求
2.8 关于其他跨域问题,比如其他的服务器会通过请求的referer信息进行访问的限制,可以通过设置
|
|
写代码的时候就经常把这两个属性弄混淆,到底是href还是src,href标识超文本引用,用在link和a等元素上,href是引用和页面关联,是在当前元素和引用资源之间建立联系,src表示引用资源,表示替换当前元素,用在img,script,iframe上,src是页面内容不可缺少的一部分。
src是source的缩写,是指向外部资源的位置,指向的内部会迁入到文档中当前标签所在的位置;在请求src资源时会将其指向的资源下载并应用到当前文档中,例如js脚本,img图片和frame等元素。
\当浏览器解析到这一句的时候会暂停其他资源的下载和处理,直至将该资源加载,编译,执行完毕,图片和框架等元素也是如此,类似于该元素所指向的资源嵌套如当前标签内,这也是为什么要把js饭再底部而不是头部。
\当浏览器解析到这一句的时候会识别该文档为css文件,会下载并且不会停止对当前文档的处理,这也是为什么建议使用link方式来加载css而不是使用@import。
补充:link和@import的区别
两者都是外部引用CSS的方式,但是存在一定的区别:
区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
区别4:ink支持使用Javascript控制DOM去改变样式;而@import不支持。
JavaScript中有一些著名的类数组对象,它们看起来很像数组:
但实际和数组又不是一回事:
|
|
|
|
|
|
|
|
通过以上四种情况,大家可以在自己电脑上输出看下结果,类数组对象的定义大家应该会有一种新的认识;
|
|
|
|
|
|
以上的栗子,大家可以将类数组的length属性去掉试一下看看,就会发现这个属性对于类数组 定义的重要性了
模板引擎 (Template Engine)是Web开发中将展现层和数据分离的一项技术。模板引擎根据一定的语义,将数据填充到模板中,产生最终的HTML页面。模板引擎渲染的位置可分为客户端和服务器端。
服务器端渲染:模板引擎在服务器端将模板和数据合成,返回最终的HTML页面
客户端渲染:将模板和数据分别传送到客户端,在客户端由JavaScript模板引擎渲染出最终的HTML视图。
注意问题
媒体查询:响应式开发
第一种不同终端的宽度自适应代码:
|
|
第二种不同终端宽度自适应代码 :代码覆盖
|
|