Traffic Light
- Red
- Yellow
- Green
1、介绍js的基本数据类型
答: Undefined、Null、Boolean、Number、String
2、js有哪些内置对象?
答:数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error
3、this对象的理解
答:this总是指向函数的直接调用者(而非间接调用者);
如果有new关键字,this指向new出来的那个对象;
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window。
4、eval是做什么的?
答:它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval(’(’+ str +’)’)。
5、DOM怎样添加、移除、移动、复制、创建和查找节点
答:
// 创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
// 添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子节点前插入一个新的子节点
// 查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() //通过元素Id,唯一性
6、null和undefined的区别?
答:
null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
undefined:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
7、new操作符具体干了什么呢?
答:
(1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
(2)属性和方法被加入到 this 引用的对象中。
(3)新创建的对象由 this 所引用,并且最后隐式的返回 this 。
8、JSON 的了解?
答:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小。
格式:采用键值对,例如:{‘age’:‘12’, ‘name’:‘back’}
9、call() 和 apply() 的区别和作用?
答:
apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。
如:function.apply(this,[1,2,3]);
call()的第一个参数是上下文,后续是实例传入的参数序列。
如:function.call(this,1,2,3);
10、如何获取UA?
答:
function whatBrowser() {
document.Browser.Name.value=navigator.appName;
document.Browser.Version.value=navigator.appVersion;
document.Browser.Code.value=navigator.appCodeName;
document.Browser.Agent.value=navigator.userAgent;
}
其他
11、哪些常见操作会造成内存泄漏?
答:
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)。
12、线程与进程的区别
答:
一个程序至少有一个进程,一个进程至少有一个线程。
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
13、如何解决跨域问题
JSONP:
原理是:动态插入script标签,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
优点是兼容性好,简单易用,支持浏览器与服务器双向通信。缺点是只支持GET请求。
JSONP:json+padding(内填充),顾名思义,就是把JSON填充到一个盒子里
14、javascript垃圾回收方法
标记清除(mark and sweep)
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting)
在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,
也就是说只要涉及BOM及DOM就会出现循环引用问题。
15、快速 排序的思想并实现一个快排?
“快速排序”的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,找一个基准点
(2)建立两个数组,分别存储左边和右边的数组
(3)利用递归进行下次比较
jquery将一些原型属性和方法封装在了jquery.prototype中,为了缩短名称,又赋值给了jquery.fn,这是很形象的写法。
有一些数组或对象的方法经常能使用到,jQuery将其保存为局部变量以提高访问速度。
jquery实现的链式调用可以节约代码,所返回的都是同一个对象,可以提高代码效率。
ES6的了解
新增模板字符串(为JavaScript提供了简单的字符串插值功能)、箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。)、for-of(用来遍历数据—例如数组中的值。)arguments对象可被不定参数和默认参数完美代替。ES6将promise对象纳入规范,提供了原生的Promise对象。增加了let和const命令,用来声明变量。增加了块级作用域。let命令实际上就增加了块级作用域。ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。。还有就是引入module模块的概念
js继承方式及其优缺点
原型链继承的缺点
一是字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。
借用构造函数(类式继承)
借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。所以我们需要原型链+借用构造函数的模式,这种模式称为组合继承
组合式继承
组合式继承是比较常用的一种继承方法,其背后的思路是 使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性。
16、defer和async
defer并行加载js文件,会按照页面上script标签的顺序执行
async并行加载js文件,下载完成立即执行,不会按照页面上script标签的顺序执行
17、用过哪些设计模式?
(1)工厂模式:
主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字。将所有实例化的代码集中在一个位置防止代码重复。
(2)工厂模式解决了重复实例化的问题 ,但还有一个问题,那就是识别问题,因为根本无法 搞清楚他们到底是哪个对象的实例。
function createObject(name,age,profession){//集中实例化的函数var obj = new Object();
obj.name = name;
obj.age = age;
obj.profession = profession;
obj.move = function () {
return this.name + ’ at ’ + this.age + ’ engaged in ’ + this.profession;
};
return obj;
}
var test1 = createObject(‘trigkit4’,22,‘programmer’);//第一个实例var test2 = createObject(‘mike’,25,‘engineer’);//第二个实例
(3)构造函数模式
使用构造函数的方法 ,即解决了重复实例化的问题 ,又解决了对象识别的问题,该模式与工厂模式的不同之处在于:
构造函数方法没有显示的创建对象 (new Object());
直接将属性和方法赋值给 this 对象;
没有 renturn 语句。
18、说说你对闭包的理解
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念
闭包有三个特性:
(1)函数嵌套函数
(2)函数内部可以引用外部的参数和变量
(3)参数和变量不会被垃圾回收机制回收
19、请你谈谈Cookie的弊端
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。
第一:每个特定的域名下最多生成20个cookie
(1)IE6或更低版本最多20个cookie
(2)IE7和之后的版本最后可以有50个cookie。
(3)Firefox最多50个cookie
(4)chrome和Safari没有做硬性限制
IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie。
cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节。
IE 提供了一种存储可以持久化用户数据,叫做userdata,从IE5.0就开始支持。每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。
优点:极高的扩展性和可用性
通过良好的编程,控制保存在cookie中的session对象的大小。
通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
Cookie
数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉.
安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
20、浏览器本地存储
在较高版本的浏览器中,js提供了sessionStorage和globalStorage。在HTML5中提供了localStorage来取代globalStorage。
html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
web storage和cookie的区别
Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。
除此之外,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。
但是cookie也是不可以或缺的:cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生
浏览器的支持除了IE7及以下不支持外,其他标准浏览器都完全支持(ie及FF需在web服务器里运行),值得一提的是IE总是办好事,例如IE7、IE6中的userData其实就是javascript本地存储的解决方案。通过简单的代码封装可以统一到所有的浏览器都支持web storage。
localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等
21、cookie 和session 的区别:
(1)cookie数据存放在客户的浏览器上,session数据放在服务器上。
(2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
(3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
(4)单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
(5)所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
22、DOM操作——怎样添加、移除、移动、复制、创建和查找节点。
1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //并没有insertAfter()
3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值(IE容错能力较强,
会得到一个数组,其中包括id等于name值的)
getElementById() //通过元素Id,唯一性
23、如何实现浏览器内多个标签页之间的通信?
调用localstorge、cookies等本地存储方式
js延迟加载的方式有哪些?
defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js
哪些操作会造成内存泄漏?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
25、列举IE 与其他浏览器不一样的特性?
(1)IE支持currentStyle,FIrefox使用getComputStyle
(2)IE 使用innerText,Firefox使用textContent
(3)滤镜方面:IE:filter:alpha(opacity= num);Firefox:-moz-opacity:num
(4)事件方面:IE:attachEvent:火狐是addEventListener
(5)鼠标位置:IE是event.clientX;火狐是event.pageX
(6)IE使用event.srcElement;Firefox使用event.target
(7)IE中消除list的原点仅需margin:0即可达到最终效果;FIrefox需要设置margin:0;padding:0以及list-style:none
(8)CSS圆角:ie7以下不支持圆角
26、javascript对象的几种创建方式
(1)工厂模式
(2)构造函数模式
(3)原型模式
(4)混合构造函数和原型模式
(5)动态原型模式
(6)寄生构造函数模式
(7)稳妥构造函数模式
27、javascript继承的6种方法
(1)原型链继承
(2)借用构造函数继承
(3)组合继承(原型+借用构造)
(4)原型式继承
(5)寄生式继承
(6)寄生组合式继承
28、创建ajax的过程
(1)创建XMLHttpRequest
对象,也就是创建一个异步调用对象.
(2)创建一个新的`HTTP`请求,并指定该`HTTP`请求的方法、`URL`及验证信息.
(3)设置响应`HTTP`请求状态变化的函数.
(4)发送`HTTP`请求.
(5)获取异步调用返回的数据.
(6)使用JavaScript和DOM实现局部刷新.
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET','demo.php','true');
xmlHttp.send()
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState === 4 & xmlHttp.status === 200){
}
}
29、异步加载和延迟加载
(1)异步加载的方案: 动态插入script标签
(2)通过ajax去获取js代码,然后通过eval执行
(3)script标签上添加defer或者async属性
(4)创建并插入iframe,让它异步执行js
(5)延迟加载:有些 js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需要的。
30、Flash、Ajax各自的优缺点,在使用中如何取舍?
Flash适合处理多媒体、矢量图形、访问机器;对CSS、处理文本上不足,不容易被搜索。
-Ajax对CSS、文本支持很好,支持搜索;多媒体、矢量图形、机器访问不足。
共同点:与服务器的无刷新传递消息、用户离线和在线状态、操作DOM
请解释一下 JavaScript 的同源策略。
概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。
指一段脚本只能读取来自同一来源的窗口和文档的属性。
为什么要有同源限制?
我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。
缺点:
现在网站的JS 都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节。
31、事件、IE与火狐的事件机制有什么区别? 如何阻止冒泡?
(1)我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。
(2)事件处理机制:IE是事件冒泡、firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件。;
(3) ev.stopPropagation()
;注意旧ie的方法 ev.cancelBubble = true
;
ajax的缺点和在I E下的问题?
详情请见:[JavaScript学习总结(七)Ajax和Http状态字][14]
32、ajax的缺点
(1)ajax不支持浏览器back按钮。
(2)安全问题 AJAX暴露了与服务器交互的细节。
(3)对搜索引擎的支持比较弱。
(4)破坏了程序的异常机制。
(5)不容易调试。
33、IE缓存问题
在IE浏览器下,如果请求的方法是GET,并且请求的URL不变,那么这个请求的结果就会被缓存。解决这个问题的办法可以通过实时改变请求的URL,只要URL改变,就不会被缓存,可以通过在URL末尾添加上随机的时间戳参数(‘t’= + new Date().getTime())
或者:
open(‘GET’,‘demo.php?rand=+Math.random()’,true);//
Ajax请求的页面历史记录状态问题
可以通过锚点来记录状态,location.hash。让浏览器记录Ajax请求时页面状态的变化。
还可以通过HTML5的history.pushState,来实现浏览器地址栏的无刷新改变
34、说说你对Promise的理解
依照 Promise/A+ 的定义,Promise 有四种状态:
pending: 初始状态, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.
rejected: 失败的操作.
settled: Promise已被fulfilled或rejected,且不是pending
另外, fulfilled 与 rejected 一起合称 settled。
Promise 对象用来进行延迟(deferred) 和异步(asynchronous ) 计算。
Promise 的构造函数
构造一个 Promise,最基本的用法如下:
var promise = new Promise(function(resolve, reject) {
if (...) { // succeed
resolve(result);
} else { // fails
reject(Error(errMessage));
}
});
Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为 thenable)。它的使用方法如下:
promise.then(onFulfilled, onRejected)
接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在 rejected 的时候被调用,接收参数就是 future,onFulfilled对应 resolve, onRejected 对应 reject。
35、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
Object.prototype.clone = function(){
var o = this.constructor === Array ? [] : {};
for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
}
return o;
}
36、说说严格模式的限制
严格模式主要有以下限制:
变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀0表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(比如protected、static和interface)
设立”严格模式”的目的,主要有以下几个:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。
注:经过测试IE6,7,8,9均不支持严格模式。
37、如何删除一个cookie
(1)将时间设为当前时间往前一点。
var date = new Date();
date.setDate(date.getDate() - 1);//真正的删除
setDate()方法用于设置一个月的某一天。
(2)expires的设置
document.cookie = ‘user=’+ encodeURIComponent(‘name’) + ';expires = ’ + new Date(0)
,和,标签
标签和 标签一样,用于强调文本,但它强调的程度更强一些。
em 是 斜体强调标签,更强烈强调,表示内容的强调点。相当于html元素中的 …;
< b > < i >是视觉要素,分别表示无意义的加粗,无意义的斜体。
em 和 strong 是表达要素(phrase elements)。
38、编写一个方法 求一个字符串的字节长度
假设:一个英文字符占用一个字节,一个中文字符占用两个字节
function GetBytes(str){
var len = str.length;
var bytes = len;
for(var i=0; i 255) bytes++;
}
return bytes;
}
alert(GetBytes(“你好,as”));
39、说说你对MVC和MVVM的理解
MVC
View 传送指令到 Controller
Controller 完成业务逻辑后,要求 Model 改变状态
Model 将新的数据发送到 View,用户得到反馈
所有通信都是单向的。
Angular它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
组成部分Model、View、ViewModel
View:UI界面
ViewModel:它是View的抽象,负责View与Model之间信息转换,将View的Command传送到Model;
Model:数据访问层
请解释什么是事件代理
事件代理(Event Delegation),又称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。
attribute和property的区别是什么?
attribute是dom元素在文档中作为html标签拥有的属性;
property就是dom元素在js中作为对象拥有的属性。
所以:
对于html的标准属性来说,attribute和property是同步的,是会自动更新的,
但是对于自定义的属性来说,他们是不同步的,
40、请描述一下 cookies,sessionStorage 和 localStorage 的区别?
(1)cookie:存储在用户本地终端上的数据。有时也用cookies,指某些网站为了辨别用户身份,进行session跟踪而存储在本地终端上的数据,通常经过加密。一般应用最典型的案列就是判断注册用户是否已经登过该网站。
(2)HTML5 提供了两种在客户端存储数据的新方法:(http://www.w3school.com.cn/html5/html_5_webstorage.asp)…两者都是仅在客户端(即浏览器)中保存,不参与和服务器的通信;
localStorage - 没有时间限制的数据存储,第二天、第二周或下一年之后,数据依然可用。
如何创建和访问 localStorage:
下面的例子对用户访问页面的次数进行计数:
sessionStorage - 针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除。
创建并访问一个 sessionStorage:
下面的例子对用户在当前 session 中访问页面的次数进行计数:
sessionStorage 、localStorage 和 cookie 之间的区别
共同点:都是保存在浏览器端,且同源的。
区别:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递;cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。
41、例举3种强制类型转换和2种隐式类型转换?
强制(parseInt,parseFloat,number)
隐式(== – ===)
42、split() join() 的区别
前者是切割成数组的形式,后者是将数组转换成字符串。
43、数组方法pop() push() unshift() shift()
Push()尾部添加,pop()尾部删除;Unshift()头部添加,shift()头部删除。
44、事件绑定和普通事件有什么区别
普通添加事件的方法:
var btn = document.getElementById(“hello”);
btn.onclick = function(){
alert(1);
}
btn.onclick = function(){
alert(2);
}
执行上面的代码只会alert 2
事件绑定方式添加事件:
var btn = document.getElementById(“hello”);
btn.addEventListener(“click”,function(){
alert(1);
},false);
btn.addEventListener(“click”,function(){
alert(2);
},false);
执行上面的代码会先alert 1 再 alert 2
普通添加事件的方法不支持添加多个事件,最下面的事件会覆盖上面的,而事件绑定(addEventListener)方式添加事件可以添加多个。
.IE和DOM事件流的区别
①执行顺序不一样;②参数不一样;③事件加不加on;④this指向问题。
45、IE和标准下有哪些兼容性的写法
Var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
Var target = ev.srcElement||ev.target。
46、ajax请求的时候get 和post方式的区别
①一个在url后面,一个放在虚拟载体里面;
②有大小限制;
③安全问题;
④应用不同:一个是论坛等只需要请求的,一个是类似修改密码的。
47、ajax请求时,如何解释json数据
使用eval parse,鉴于安全性考虑,使用parse更靠谱。
48、写一个获取非行间样式的函数
function getStyle(obj,attr,value)
{
if(!value)
{
if(obj.currentStyle)
{
return obj.currentStyle(attr)
}
else
{
obj.getComputedStyle(attr,false)
}
}
else
{
obj.style[attr]=value
}
}
49、事件委托是什么
让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
50、如何阻止事件冒泡和默认事件
canceBubble return false
51、谈性能优化问题
代码层面:避免使用css表达式,避免使用高级选择器,通配选择器。
缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等
请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
请求带宽:压缩文件,开启GZIP,
代码层面的优化
用hash-table来优化查找
少用全局变量
用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能
用setTimeout来避免页面失去响应
缓存DOM节点查找的结果
避免使用CSS Expression
避免全局查询
避免使用with(with会创建自己的作用域,会增加作用域链长度)
多个变量声明合并
避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率
尽量避免写在HTML标签中写Style属性
51、解释jsonp的原理,以及为什么不是真正的ajax
动态创建script标签,回调函数;Ajax是页面无刷新请求数据操作
52、javascript的本地对象,内置对象和宿主对象
本地对象为array obj regexp等可以new实例化
内置对象为gload Math 等不可以实例化的
宿主为浏览器自带的document,window 等
53、document load 和document ready的区别
Document.onload 是在结构和样式加载完才执行js
Document.ready原生种没有这个方法,jquery中有 $().ready(function)
54、””和“=”的不同
前者会自动转换类型
后者不会
55、javascript的同源策略
一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合
编写一个数组去重的方法
function oSort(arr)
{
var result ={};
var newArr=[];
for(var i=0;i
if(!result[arr])
{
newArr.push(arr)
result[arr]=1
}
}
return newArr
}
56、Ajax你以前用过么?简单介绍一下
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用AJAX)如果需要更新内容,必需重载整个网页面。有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。
57、 Ajax可以做异步请求么?
可以。Ajax请求默认是异步的.如果想同步把async设置为false就可以了默认是true。如果是jquery $.ajax({ url: some.php, async: false, success : function(){ } }); 如果是原生的js xmlHttp.open(“POST”,url,false)。
58、一网站如果有大量的人登陆访问。那么会产生很多的session,如果你是程序员你该怎么办。
session默认保存在内存中,内存资源宝贵,session数据量大导致内存利用率高,以下方案解决session内存存储问题:
(1)可以设置session超时时间,达到超时时间session自动清空
20
(2)将session中的数据序列化到硬盘中;
不使用session,使用cookie(此方法存在安全性问题)
59、Ajax如何实现异步定时5秒刷新?
setInterval(function() {
$("#content").load(location.href+" #content>*","");
}, 5000);
60、如何实现浏览器内多个标签页之间的通信?
调用localstorge、cookies等本地存储方式。
方法一:
localstorge在一个标签页里被添加、修改或删除时,都会触发一个storage事件,通过在另一个标签页里监听storage事件,即可得到localstorge存储的值,实现不同标签页之间的通信。
标签页1:
[html] view plain copy
1.
2.
3.
方法二:
使用cookie+setInterval,将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。
标签页1:
[html] view plain copy
1.
2.
3.
61、页面可见性(Page Visibility)API 可以有哪些用途?
页面可见性: 就是对于用户来说,页面是显示还是隐藏, 所谓显示的页面,就是我们正在看的页面;隐藏的页面,就是我们没有看的页面。 因为,我们一次可以打开好多标签页面来回切换着,始终只有一个页面在我们眼前,其他页面就是隐藏的,还有一种就是…,(把浏览器最小化,所有的页面就都不可见了)。
API 很简单,document.hidden 就返回一个布尔值,如果是true, 表示页面可见,false 则表示,页面隐藏。 不同页面之间来回切换,触发visibilitychange事件。 还有一个document.visibilityState, 表示页面所处的状态,取值:visible, hidden 等四个。
document.addEventListener(“visibilitychange”, function(){
if(document.hidden){
document.title =“hidden”;
}else {
document.title = “visibile”;
}
})
我们打开这个页面,然后再打开另一个页面,来回点击这两个页面,当我们看到这个页面时,标题显示visiable ,当我们看另一个页面时,标题显示hidden;
动画,视频,音频都可以在页面显示时打开,在页面隐藏时关闭。
62、JavaScript原型,原型链 ?
js原型?
js每声明一个function,都有prototype原型,prototype原型是函数的一个默认属性,在函数的创建过程中由js编译器自动添加。
也就是说:当生产一个function对象的时候,就有一个原型prototype。
举个栗子:
是不是还看到了一个_proto_的属性?!骚年,你的眼睛不错~待会在解释prototype和_proto_的基友关系!
prototype的属性值是一个对象,是属性的集合,是属性的集合,是属性的集合,
Js原型链是实现继承的主要方法。其基本思想是:利用原型让一个引用类型继承另一个应用类型的属性和方法。
简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
首先,我觉得有必要先解释一下prototype 和_proto_之间的关系。
每一个基本对象都有自己的_proto_属性,而每一个函数对象都有自己的prototype原型(函数对象也属于基本对象,所以也有_proto_),每当去定义一个prototype的时候,就相当于把该实例的__proto__指向一个结构体,那么这个被指向结构体就称为该实例的原型。 我们还是来看图吧~比较清晰:
1
2
3
4 var foo = {
x: 10,
y: 20
};
解析:当你定义一个函数对象的时候,其内部就有这样一个链表关系。声明foo对象,自带了_proto_的属性,而这个属性指向了prototype,从而实现对象的扩展(例如继承等操作)。
63、Javascript创建对象的几种方式?
javascript是一种“基于prototype的面向对象语言“,与java有非常大的区别,无法通过类来创建对象。那么,既然是面象对象的,如何来创建对象呢?
一、通过”字面量“方式创建。
方法:将成员信息写到{}中,并赋值给一个变量,此时这个变量就是一个对象。
例如:
var person = (name:‘dongjc’, work:function() {console.log(‘write coding’)});
如果{}中为空,则将创建一个空对象:
var person = {} //创建空对象
演示代码:
1
64、Javascript作用链域?
JavaScript中所有的量都是存在于某一个作用域中的
除了全局作用域, 每一个作用域都是存在於某个作用域中的
在试图访问一个变量时JS引擎会从当前作用域开始向上查找直到Global全局作用域停止
例如
1
2
3
4
5
6
7
8
9
10 var A;//全局作用域
function B()
{
var C;//C位于B函数的作用域
function D()
{
var E;//E位于D函数的作用域
alert(A)
}
}
当alert(A)时, JS引擎沿着D的作用域, B的作用域, 全局作用域的顺序进行查找.
这三个作用域组成的有序集合就成为作用域链
至于为什么叫链, 你可以理解和链表有相似之处, 深层的作用域会能够访问到上层作用域, 就如同链表中两个连续节点能够单向访问一样
65、什么是window对象? 什么是document对象?
简单来说,document是window的一个对象属性。
Window 对象表示浏览器中打开的窗口。
如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为每个框架创建一个额外的 window 对象。
所有的全局函数和对象都属于Window 对象的属性和方法。
document 对 Document 对象的只读引用。
[window对象]
它是一个顶层对象,而不是另一个对象的属性,即浏览器的窗口。
属性
defaultStatus 缺省的状态条消息
document 当前显示的文档(该属性本身也是一个对象)
frame 窗口里的一个框架((FRAME>)(该属性本身也是一个对象)
frames array 列举窗口的框架对象的数组,按照这些对象在文档中出现的顺序列出(该属性本身也是一个
对象)
history 窗口的历史列表(该属性本身也是一个对象)
length 窗口内的框架数
location 窗口所显示文档的完整(绝对)URL(该属性本身也是一个对象)不要把它与如document.location
混淆,后者是当前显示文档的URL。用户可以改变window.location(用另一个文档取代当前文档),但却不能改变
document.location (因为这是当前显示文档的位置)
name 窗口打开时,赋予该窗口的名字
opener 代表使用window.open打开当前窗口的脚本所在的窗口(这是Netscape Navigator 3.0beta 3所引
入的一个新属性)
parent 包含当前框架的窗口的同义词。frame和window对象的一个属性
self 当前窗口或框架的同义词
status 状态条中的消息
top 包含当前框架的最顶层浏览器窗口的同义词
window 当前窗口或框架的同义词,与self相同
方法
alert() 打开一个Alert消息框
clearTimeout() 用来终止setTimeout方法的工作
close() 关闭窗口
confirm() 打开一个Confirm消息框,用户可以选择OK或Cancel,如果用户单击OK,该方法返回true,单击
Cancel返回false
blur() 把焦点从指定窗口移开(这是Netscape Navigator 3.0 beta 3引入的新方法)
focus() 把指定的窗口带到前台(另一个新方法)
open() 打开一个新窗口
prompt() 打开一个Prompt对话框,用户可向该框键入文本,并把键入的文本返回到脚本
setTimeout() 等待一段指定的毫秒数时间,然后运行指令事件处理程序事件处理程序
Onload() 页面载入时触发
Onunload() 页面关闭时触发
[document 对象]
该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。
属性
alinkColor 活动链接的颜色(ALINK)
anchor 一个HTMI锚点,使用标记创建(该属性本身也是一个对象)
anchors array 列出文档锚点对象的数组()(该属性本身也是一个对象)
bgColor 文档的背景颜色(BGCOLOR)
cookie 存储于cookie.txt文件内的一段信息,它是该文档对象的一个属性
fgColor 文档的文本颜色(标记里的TEXT特性)
form 文档中的一个窗体()(该属性本身也是一个对象)
forms anay 按照其出现在文档中的顺序列出窗体对象的一个数组(该属性本身也是一个对象)
lastModified 文档最后的修改日期
linkColor 文档的链接的颜色,即标记中的LINK特性(链接到用户没有观察到的文档)
link 文档中的一个标记(该属性本身也是一个对象)
links array 文档中link对象的一个数组,按照它们出现在文档中的顺序排列(该属性本身也是一个对象)
location 当前显示文档的URL。用户不能改变document.location(因为这是当前显示文档的位置)。但是,
可以改变 window.location (用其它文档取代当前文档)window.location本身也是一个对象,而
document.location不是对象
referrer 包含链接的文档的URL,用户单击该链接可到达当前文档
title 文档的标题((TITLE>)
vlinkColor 指向用户已观察过的文档的链接文本颜色,即标记的VLINK特性
方法
clear 清除指定文档的内容
close 关闭文档流
open 打开文档流
write 把文本写入文档
writeln 把文本写入文档,并以换行符结尾
区别:1、window 指窗体。document指页面。document是window的一个子对象。
2、用户不能改变 document.location(因为这是当前显示文档的位置)。但是,可以改变window.location (用其它文档取代当前文档)window.location本身也是一个对象,而document.location不是对象
66、写一个通用的事件侦听器函数
1. markyun.Event = {
2. // 页面加载完成后
3. readyEvent : function(fn) {
4. if (fn==null) {
5. fn=document;
6. }
7. var oldonload = window.onload;
8. if (typeof window.onload != ‘function’) {
9. window.onload = fn;
10. } else {
11. window.onload = function() {
12. oldonload();
13. fn();
14. };
15. }
16. },
17. // 视能力分别使用dom0||dom2||IE方式 来绑定事件
18. // 参数: 操作的元素,事件名称 ,事件处理程序
19. addEvent : function(element, type, handler) {
20. if (element.addEventListener) {
21. //事件类型、需要执行的函数、是否捕捉
22. element.addEventListener(type, handler, false);
23. } else if (element.attachEvent) {
24. element.attachEvent(‘on’ + type, function() {
25. handler.call(element);
26. });
27. } else {
28. element[‘on’ + type] = handler;
29. }
30. },
31. // 移除事件
32. removeEvent : function(element, type, handler) {
33. if (element.removeEnentListener) {
34. element.removeEnentListener(type, handler, false);
35. } else if (element.datachEvent) {
36. element.detachEvent(‘on’ + type, handler);
37. } else {
38. element[‘on’ + type] = null;
39. }
40. },
41. // 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
42. stopPropagation : function(ev) {
43. if (ev.stopPropagation) {
44. ev.stopPropagation();
45. } else {
46. ev.cancelBubble = true;
47. }
48. },
49. // 取消事件的默认行为
50. preventDefault : function(event) {
51. if (event.preventDefault) {
52. event.preventDefault();
53. } else {
54. event.returnValue = false;
55. }
56. },
57. // 获取事件目标
58. getTarget : function(event) {
59. return event.target || event.srcElement;
60. },
61. // 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
62. getEvent : function(e) {
63. var ev = e || window.event;
64. if (!ev) {
65. var c = this.getEvent.caller;
66. while © {
67. ev = c.arguments[0];
68. if (ev && Event == ev.constructor) {
69. break;
70. }
71. c = c.caller;
72. }
73. }
74. return ev;
75. }
76. };
67、[“1”, “2”, “3”].map(parseInt) 答案是多少?
[1,NaN,NaN]
68、关于事件,IE与火狐的事件机制有什么区别? 如何阻止冒泡?
我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。
事件处理机制:IE是事件冒泡、火狐是 事件捕获;
ev.stopPropagation();
69、什么是闭包(closure),为什么要用它?
闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性:
(1)函数内再嵌套函数
(2)内部函数可以引用外层的参数和变量
(3)参数和变量不会被垃圾回收机制回收
HTML:
JS:
然后我们看看下面的一段代码,这是对闭包作用的非常直白的描述:
function say667() {// Local variable that ends up within closure
var num = 666;
var sayAlert = function() {
alert(num);
}
num++;
return sayAlert;
}var sayAlert = say667();
sayAlert()//执行结果应该弹出的667
执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在
使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源
因为say667()的内部函数的执行需要依赖say667()中的变量
70、javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?
除了正常运行模式,ECMAscript 5添加了第二种运行模式:“严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
为什么用严格模式
71、如何判断一个对象是否属于某个类?
javascript中检测对象的类型的运算符有:typeof、constructor、instanceof。
typeof:typeof是一个一元运算符,返回结果是一个说明运算数类型的字符串。如:“number”,“string”,“boolean”,“object”,“function”,“undefined”(可用于判断变量是否存在)。 但 typeof 的能力有限,其对于Date、RegExp、Array类型返回的都是"object"。所以它只在区别对象和原始类型的时候才有用。要区一种对象类型和另一种对象类型,必须使用其他的方法。
instanceof 运算符:instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。instanceof方法可以判断变量是否是数组类型,但是只限同一全局环境之内,在一个页面有多个iframe的情况下,instanceof失效。
constructor 属性: JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。
Object.prototype.toString.call():该方法是目前为止发现的判断一个对象类型的最好的办法。
72、Javascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?
hasOwnProperty
74、js延迟加载的方式有哪些?
js的延迟加载有助与提高页面的加载速度,以下是延迟加载的几种方法:
(1)使用setTimeout延迟方法的加载时间
延迟加载js代码,给网页加载留出更多时间
(2)让js最后加载
例如引入外部js脚本文件时,如果放入html的head中,则页面加载前该js脚本就会被加载入页面,而放入body中,则会按照页面从上倒下的加载顺序来运行javascript的代码~~~ 所以我们可以把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度
(3)上述方法2也会偶尔让你收到Google页面速度测试工具的“延迟加载javascript”警告。所以这里的解决方案将是来自Google帮助页面的推荐方案。
//这些代码应被放置在标签前(接近HTML文件底部)
这段代码意思是等到整个文档加载完后,再加载外部文件“defer.js”。
使用此段代码的步骤:
1).复制上面代码
2).粘贴代码到HTML的标签前 (靠近HTML文件底部)
3).修改“defer.js”为你的外部JS文件名
4).确保你文件路径是正确的。例如:如果你仅输入“defer.js”,那么“defer.js”文件一定与HTML文件在同一文件夹下。
注意:这段代码直到文档加载完才会加载指定的外部js文件。因此,不应该把那些页面正常加载需要依赖的javascript代码放在这里。而应该将JavaScript代码分成两组。一组是因页面需要而立即加载的javascript代码,另外一组是在页面加载后进行操作的javascript代码(例如添加click事件或其他东西)。这些需等到页面加载后再执行的JavaScript代码,应放在一个外部文件,然后再引进来。
75、同步和异步的区别?
同步:
同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。
异步:
将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。
同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。
异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。
异步操作例子:
为了避免短时间大量的数据库操作,就使用缓存机制,也就是消息队列。先将数据放入消息队列,然后再慢慢写入数据库。
引入消息队列机制,虽然可以保证用户请求的快速响应,但是并没有使得我数据迁移的时间变短(即80万条数据写入mysql需要1个小时,用了redis之后,还是需要1个小时,只是保证用户的请求的快速响应。用户输入完http url请求之后,就可以把浏览器关闭了,干别的去了。如果不用redis,浏览器不能关闭)。
同步就没有任何价值了吗?
银行的转账功能。
76、页面编码和被请求的资源编码如果不一致如何处理?
s编码和页面编码不一致,导致提示变量未定义的解决方法 (2011-06-30 10:27:02)转载▼
标签: js跨域 变量未定义 js编码 it 分类: JS
今天在测试项目的时候,由于是和其他站合作的,引用合作方的js文件,
有个js函数调用,调用时会使用包含合作方js里的变量,
可是竟然不兼容ie6、ie7、360等主流浏览器。那必须得解决是吧。
原本以为是跨域问题,如果是跨域问题,也应该提示没权限,可是没提示。
提示的是某某变量未定义,我就百度了。 没找到我想要的答案,
灵机一动想到是不是编码问题 。于是在js后加了 charset=“utf-8” 这个 。
发现还真好了。 。 绕了好些圈子 。 这次记下了。避免下次再遇到类似的状况。
比如:http://www.yyy.com/a.html 中嵌入了一个http://www.xxx.com/test.js
a.html 的编码是gbk或gb2312的。 而引入的js编码为utf-8的 ,那就需要在引入的时候
同理,如果你的页面是utf-8的,引入的js是gbk的,那么就需要加上charset=“gbk”.
77、AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?
AMD
AMD规范其实只有一个主要接口 define(id,dependencies,factory),它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置
[javascript] view plain copy
1.define(“module”, [“dep1”, “dep2”], function(d1, d2) {
2. return someExportedValue;
3.});
4.require([“module”, “…/file”], function(module, file) { /* … */ });
优点:
适合在浏览器环境异步加载
并行加载多个模块
缺点:
提高开发成本,代码阅读和书写比较困难
不符合通用的模块思维方式,是一种妥协的实现
CMD
CMD规范和AMD相似,尽量保持简单,并且与CommonJS和NodeJS的Modules规范保持了很大的兼容性。
[javascript] view plain copy
1.define(function(require, exports, module) {
2. var $ = require(‘jquery’);
3. var Spinning = require(’./spinning’);
4. exports.doSomething = …
5. module.exports = …
6.})
优点:
依赖就近,延迟执行
很容易在node中运行
缺点:
依赖SPM打包,模块的加载逻辑偏重
78、谈一谈你对ECMAScript6的了解?
ES6 包含了很多新的语言功能,且这些语言功能使得 JS 更加强大更富有表现力。
ECMAScript 的范围是什么?
JavaScript 编程语言是由 ECMAScript 名下的 ECMA 进行标准化制定的( ECMA 是和 W3C 一样的标准化组织 )。除此之外,ECMAScript 可如下定义:
语法-解析规则,关键字,语句,声明,操作等等。
类型-布尔型,数字,字符串,对象等等。
原型和继承。
内置对象和函数的标准库 - JSON ,数学( Math ), 数组方法( Array methods ),对象内省的方法( Object introspection methods )等等。
其没有定义与 HTML 、CSS 或者 Web API 交互的内容,比如 DOM ( 文档对象模型 )。那些都是在单独的标准中定义的。 ECMAScript 不仅在浏览器环境中的涵盖了 JS 的所有方面,其在非浏览器环境中也涵盖了 JS ,例如 node.js 。
新的标准
上周, ECMAScript 语言规范的最终草案,第 6 版,被提交给 ECMA 大会进行审查。这意味着什么呢?
这意味着这个夏天,对于核心的 JavaScript 编程语言,我们将有一个新的标准。
这是一个大新闻。新的 JS 语言不是每天都可能出现的。 上一个版本,ES5,可以追溯到 2009 年。从那时起,ES 标准委员会就一直致力于 ES6 的制定直至今日。
ES6 是语言的一次重大的升级。同时,你的 JS 代码也可以继续工作。ES6 被设计为可以最大程度兼容现有的代码。事实上,很多浏览器已经支持丰富的 ES6 的功能,同时实现工作也正在进行中。这就意味着你所有的 JS 代码已经可以在那些实现一些 ES6 功能的浏览器里面运行!如果你到现在还没有看到任何兼容性问题,你可能永远也不会碰到这些问题了。
计数到 6
ECMAScript 标准的先前的版本分别编号为 1,2,3 和 5。
第四版本发生了什么?第 4 版的 ECMAScript 曾是在计划之中的,并且事实上大量的工作也已经完成了。但由于它过于的繁琐,其最终被废弃了。 ( 例如,它在静态类型系统中对泛型和类型推断有一个复杂的选择。)
ES4 是有争议的。当标准委员会最终停止继续制定时,该委员会成员同意出版一个相对温和的 ES5 ,然后继续工作以制定更多的有较大幅度改进的新功能。这个直接通过谈判达成的协议被称为“和谐(Harmony)”,这也是为什么 ES5 规范包含这两句话:
ECMAScript 是一个充满活力的语言且其语言的演化还不完整。在未来的 ECMAScript 的版本中将有较大提升的技术的声明。
这种说法也可以被看作是委员会给出的一个承诺。
兑现承诺
ES5 在 2009 年对语言进行了更新,其介绍了 Object.create( ), Object.defineProperty( ), getter 和 setter 方法,strict 模式和 JSON 对象。我已经使用了所有的这些功能,而且我喜欢 ES5 对语言做出的贡献。但是, 这些功能中的任何一种都没有对我写 JS 代码的方式产生巨大的影响。对我来说其最重要的创新,很可能是新的数组方法:.MAP,filter 等等。
然而,ES6 是决然不同的。它是多年和谐工作的产物。 同时,它是新的语言和库功能的宝库,其是迄今为止 JS 的最实质性的升级。 其新功能涵盖面很广,从那些很受欢迎的能带来便利的功能(如箭头的功能和简单的字符串插值),到能带来头脑风暴的概念(如代理和生成器)。
ES6 将改变你写 JS 代码的方式。
本系列旨在向你展示 ES6 如何通过检查其新功能来给JavaScript程序员提供新的写代码体验。
我们将以一个典型的“功能缺失”作为开始。“功能缺失”是我在过去的十年的时间内一直渴望能从 JavaScript 那看到的。所以,让我们一起去探索 ES6 迭代器和新的 for-of 循环。
79、ECMAScript6 怎么写class么,为什么会出现class这种东西?
ES6 的 class 有优点也有缺点,整体说来,是利大于弊的,推荐使用。
缺点主要有:
(1)语法和语义难对上了,也就是说从书写出来的代码是看不出来内部是通过原型实现相关功能点的。
(2)类的写法有一定的限制性,不再像原型那么灵活了。
优点主要有:
(1)语法更加紧凑,更加符合传统面相对象的写法了。
(2)使 IDE 、类型检查器、代码风格检查器等工具更方便地检测代码语法,做静态分析。
(3) ES6 的类可以继承内置类,并使某些属性和内置类有一样的行为。比如可以继承 Array ,并且子类的 length 属性和 Array 的 length 属性一样会随着元素个数的变化而自动变化。
(4)兼容以前的代码。
(5)使初学者入门更快。
(6)不再需要第三方的继承库。
最后, ES6 的类只是一个基础形式,后续 ECMAScript 版本还会继续添加一些内容进去,比如 trait 、不可变实例等。
其实,从多人开发的大型项目来看,其中使用的大多数语言都包含了类这个元素,并且类在这些项目中还被广泛使用。这就说明类有利于多人大型项目的开发。而 ES6 引入类,也表明了现在的 js 项目越来越复杂了,同时也为 js 在服务器端舞台上大放异彩奠定基础。
80、documen.write和 innerHTML的区别?
(1).write是DOM方法,向文档写入HTML表达式或JavaScript代码,可列出多个参数,参数被顺序添加到文档中 ;innerHTML是DOM属性,设置或返回调用元素开始结束标签之间的HTML元素。
(2)两者都可向页面输出内容,innerHTML比document.write更灵活。
当文档加载时调用document.write直接向页面输出内容,文档加载结束后调用document.write输出内容会重写整个页面。通常按照两种的方式使用 write() 方法:一是在使用该方在文档中输出 HTML,二是在调用该方法的的窗口之外的窗口、框架中产生新文档(务必使用close关闭文档)。
在读模式下,innerHTML属性返回与调用元素的所有子节点对应的HTML标记,在写模式下,innerHTML会根据指定的值创建新的DOM树替换调用元素原先的所有子节点。
(3)两者都可动态包含外部资源如JavaScript文件
通过document.write插入
81、JS 怎么实现一个类。怎么实例化这个类
严格的说,JavaScript 是基于对象的编程语言,而不是面向对象的编程语言。
在面向对象的编程语言中(如Java、C++、C#、PHP等),声明一个类使用 class 关键字。
例如:
1.public class Person{}
但是在JavaScript中,没有声明类的关键字,也没有办法对类的访问权限进行控制。
JavaScript 使用函数来定义类。
语法:
function className(){
// 具体操作
}
例如,定义一个Person类:
function Person() {
this.name=" 张三 “; // 定义一个属性 name
this.sex=” 男 "; // 定义一个属性 sex
this.say=function(){ // 定义一个方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性别是 " + this.sex + “。”);
}
}
说明:this 关键字是指当前的对象。
创建对象(类的实例化)
创建对象的过程也是类实例化的过程。
在JavaScript中,创建对象(即类的实例化)使用 new 关键字。
语法:
new className();
将上面的 Person 类实例化:
var zhangsan=new Person();
zhangsan.say();
运行代码,输出如下内容:
嗨!大家好,我的名字是 张三 ,性别是 男 。
定义类时可以设置参数,创建对象时也可以传递相应的参数。
下面,我们将Person类重新定义:
function Person(name,sex) {
this.name=name; // 定义一个属性 name
this.sex=sex; // 定义一个属性 sex
this.say=function(){ // 定义一个方法 say()
document.write("嗨!大家好,我的名字是 " + this.name + " ,性别是 " + this.sex);
}
}
var zhangsan=new Person(“小丽”,“女”);
zhangsan.say();
运行代码,输出如下内容:
嗨!大家好,我的名字是 小丽 ,性别是 女 。
82、jquery中如何将数组转化为json字符串,然后再转化回来?
现代浏览器中提供了JSON.stringify()方法 将数组,对象转成json。
JSON.stringify 把一个对象转换成json字符串,
JSON.parse 把一个json字符串解析成对象。
不支持的可以引入json2.js
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
}
然后调用:
$("").stringifyArray(array)
83、jQuery 的属性拷贝(extend)的实现原理是什么,如何实现深拷贝?
语法:jQuery.extend( [deep ], target, object1 [, objectN ] )
描述: 将两个或更多对象的内容合并到第一个对象。
关于 . e x t e n d ( ) 的 用 法 网 上 有 很 多 文 章 , 在 这 里 指 向 写 写 对 深 浅 拷 贝 的 理 解 深 浅 拷 贝 对 应 的 参 数 就 是 [ d e e p ] , 是 可 选 的 , 为 t r u e 或 f a l s e 。 默 认 情 况 是 f a l s e ( 浅 拷 贝 ) , 并 且 f a l s e 是 不 能 够 显 示 的 写 出 来 的 。 如 果 想 写 , 只 能 写 t r u e ( 深 拷 贝 ) 什 么 是 深 、 浅 拷 贝 呢 ? 先 讲 定 义 , 再 举 例 子 在 默 认 情 况 下 , 通 过 .extend()的用法网上有很多文章,在这里指向写写对深浅拷贝的理解 深浅拷贝对应的参数就是[deep],是可选的,为true或false。默认情况是false(浅拷贝),并且false是不能够显示的写出来的。如果想写,只能写true(深拷贝)~~ 什么是深、浅拷贝呢?先讲定义,再举例子 在默认情况下,通过 .extend()的用法网上有很多文章,在这里指向写写对深浅拷贝的理解深浅拷贝对应的参数就是[deep],是可选的,为true或false。默认情况是false(浅拷贝),并且false是不能够显示的写出来的。如果想写,只能写true(深拷贝) 什么是深、浅拷贝呢?先讲定义,再举例子在默认情况下,通过.extend()合并操作不是递归的(浅拷贝);如果第一个对象的属性本身是一个对象或数组,那么它将完全用第二个对象相同的key重写一个属性。这些值不会被合并。然而,如果将 true 作为该函数的第一个参数,那么会在对象上进行递归的合并(深拷贝)。
浅拷贝(false 默认):如果第二个参数对象有的属性第一个参数对象也有,那么不会进行相同参数内部的比较,直接将第一个对象的相同参数覆盖。
深拷贝(true):如果第二个参数对象有的属性第一个参数对象也有,还要继续在这个相同的参数向下一层找,比较相同参数的对象中是否还有不一样的属性,如果有,将其继承到第一个对象,如果没有,则覆盖。
var object1 = {
apple: 0,
banana: {
weight: 52,
price: 100
},
cherry: 97
};var object2 = {
banana: {
price: 200
},
durian: 100
};
//默认情况浅拷贝
//object1—>{“apple”:0,“banana”:{“price”:200},“cherry”:97,“durian”:100}
//object2的banner覆盖了object1的banner,但是weight属性未被继承
//$.extend(object1, object2);
//深拷贝
//object1—>{“apple”:0,“banana”:{“weight”:52,“price”:200},“cherry”:97,“durian”:100}
//object2的banner覆盖了object1的banner,但是weight属性也被继承了呦
$.extend(true,object1, object2);
console.log(‘object1—>’+JSON.stringify(object1));
84、jquery.extend 与 jquery.fn.extend的区别?
(1). jQuery.extend(object);
它是为jQuery类添加类方法,可以理解为添加静态方法。如:
a.jQuery.extend({
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
});
jQuery.min(2,3); // 2
jQuery.max(4,5); // 5
b. jQuery.extend(target, object1, [objectN])用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
var settings = { validate: false, limit: 5, name: “foo” };
var options = { validate: true, name: “bar” };
jQuery.extend(settings, options);
结果:settings == { validate: true, limit: 5, name: “bar” }
(2). jQuery.fn.extend(object);
$.fn是什么?
$.fn是指jQuery的命名空间,fn上的成员(方法function及属性property),会对jQuery实例每一个有效。
查看jQuery代码,就不难发现。
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {//…
};
原来 jQuery.fn = jQuery.prototype.
所以,它是对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。
比如我们要开发一个插件,做一个特殊的编辑框,当它被点击时,便alert 当前编辑框里的内容。可以这么做:
KaTeX parse error: Expected '}', got 'EOF' at end of input: … (this).click(function(){
alert($(this).val());
});
}
});
$("#input1").doAlertWhileClick(); // 页面上为:
$("#input1") 为一个jQuery实例,当它调用成员方法 doAlertWhileClick后,便实现了扩展,每次被点击时它会先弹出目前编辑里的内容。
85、谈一下Jquery中的bind(),live(),delegate(),on()的区别?
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数
$(“a”).bind(“click”,function(){alert(“ok”);});
live(type,[data],fn) 给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的
$(“a”).live(“click”,function(){alert(“ok”);});
delegate(selector,[type],[data],fn) 指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数
$("#container").delegate(“a”,“click”,function(){alert(“ok”);})
on(events,[selector],[data],fn) 在选择元素上绑定一个或多个事件的事件处理函数
差别:
.bind()是直接绑定在元素上
.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的,绑定到document DOM节点上。和.bind()的优势是支持动态数据。
.delegate()则是更精确的小范围使用事件代理,性能优于.live()
.on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制
86、JQuery一个对象可以同时绑定多个事件,这是如何实现的?
.jQuery("#id").click(func1).mouseover(func2)//方法连写,func为方法的名字
.jQuery("#id").click(function(){//你的具体方法实现}),mouser(function(){//你的具体方法实现});
.jQuery("#id").bind(“click mouseover”,func)//两个事件中间有空格 ,func为方法的名字
.jQuery("#id").bind(“load scroll”,function(){//你的具体方法实现});
87、是否知道自定义事件。jQuery里的fire函数是什么意思,什么时候用?
1种是把那个函数放到ready函数外面。 第2种是在ready函数里面加上window.deleteStu = deleteStu; 即: $(function(){ function deleteStu(id){ alert(id); } window.deleteStu = deleteStu; }
88、jQuery 是通过哪个方法和 Sizzle 选择器结合的?
什么是jQuery选择器?
jQuery选择器通俗来讲就是一个获取html元素的工具。比如, ( " p " ) 选 取 < p > 元 素 , ("p") 选取 <p> 元素, ("p")选取<p>元素,(“p”)是jQuery的选择器的写法,这么写就可以获取(选取)html里的
元素。
jQuery选择器包括元素选择器、属性选择器、CSS选择器。(个人感觉这个分类比较扯淡)
注意:属性选择器的意思并不是选择属性,而是根据属性选择元素。
什么叫html元素?什么是属性?
html代码里的开始标签+内容+结束标签就构成一个元素,英文是element。
这是一个标签,
这也是一个标签,英文是tag。XXX
这就是一个元素。 特殊的不用jQuery选择器的话是如何实现该功能的?
如果不用jQeury,简单的元素选择器的一般原生js写法是:getElementById()、getElementByClassName()等函数获取元素。在这种情况下, 的 作 用 仅 仅 是 简 化 了 代 码 的 书 写 方 法 。 当 然 , 这 只 是 最 简 单 的 情 况 下 。 的作用仅仅是简化了代码的书写方法。 当然,这只是最简单的情况下。 的作用仅仅是简化了代码的书写方法。当然,这只是最简单的情况下。写法的在这种情况下其实也是调用getElementById(),但复杂情况则通过jQuery选择器的复杂实现。
jQuery选择器是如何实现的?
w3c上说:jQuery 使用 CSS 选择器来选取 HTML 元素。。
什么是sizzle?
sizzle是一个纯js的CSS选择器引擎(A pure-JavaScript CSS selector engine)。最新版本是2.1.1(jquery-sizzle-2.1.1-jquery.2.1.2-11-gf8ef711.zip)。
它是jQuery官网的一部分。(jQuery官网一共有5部分:jQuery、jQueryUI、jQueryMobile、Sizzle、QUnit)但它是独立的,虽然jQuery本身使用sizzle,但是你完全可以在不使用jQuery的情况下使用sizzle。
89、针对 jQuery性能的优化方法?
(1)总是使用#id去寻找element.
在jQuery中最快的选择器是ID选择器 ($(’#someid’)). 这是因为它直接映射为JavaScript的getElementById()方法。
选择单个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1 var traffic_button = $(’#content .button’);
取而代之的是直接选择button:
1 var traffic_button = $(’#traffic_button’);
选择多个元素
在我们讨论选择多个元素的时候,我们真正需要知道的是DOM的遍历和循环才是性能低下的原因。为了尽量减少性能损失, 总是使用最近的父ID去寻找。
1 var traffic_lights = $(’#traffic_light input’);
(2)在Classes前面使用Tags
在jQuery中第二快的选择器就是Tag选择器 ($(‘head’)). 而这是因为它直接映射到JavaScript的getElementsByTagName()方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1 var active_light = $(’#traffic_light input.on’);
注意:在jQuery里Class选择器是最慢的一个选择器;在IE中它循环整个DOM。可能的话尽量避免使用它。不要在ID前面 加Tags。例如,它会因为去循环所有的
1 var content = $(‘div#content’);
按照同样的思路,从多个ID传下来是冗余的。
1 var traffic_light = $(’#content #traffic_light’);
(3)缓存jQuery对象
养成保存jQuery对象到一个变量上(就像上面的例子)的习惯。例如,不要这样做:
?
1
2
3
4
5
6
7 $(’#traffic_light input.on).bind(‘click’, function(){…});
$(’#traffic_light input.on).css(‘border’, ‘3px dashed yellow’);
$(’#traffic_light input.on).css(‘background-color’, ‘orange’);
$(’#traffic_light input.on).fadeIn(‘slow’);
取而代之,首现保存jQuery变量到一个本地变量后,再继续你的操作。
1
2
3
4
5
6
7
8
9 var $active_light = $(’#traffic_light input.on’);
$active_light.bind(‘click’, function(){…});
$active_light.css(‘border’, ‘3px dashed yellow’);
$active_light.css(‘background-color’, ‘orange’);
a c t i v e l i g h t . f a d e I n ( ′ s l o w ′ ) ; 提 示 : 使 用 active_light.fadeIn('slow'); 提示:使用 activelight.fadeIn(′slow′);提示:使用前辍表示我们的本地变量是一个jQuery包集。记住,不要在你的应该程序里出现一次以上的jQuery重复的选择操作。 额外提示:延迟存储jQuery对象结果。
如果你想在你的程序的其它地方使用jQuery结果对象(result object(s)),或者你的函数要执行多次,要把它缓存在一个全局范围的对象里。通过定义一个全局容器保存jQuery结果对象,就可以在其它的函数里引用它。
// Define an object in the global scope (i.e. the window object)
window.$my ={
// Initialize all the queries you want to use more than once
head : $(‘head’),
traffic_light : $(’#traffic_light’),
traffic_button : KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲traffic_button'…my.head.append(script);
// When working inside functions, continue to save jQuery results
// to your global container.
$my.cool_results = KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲some_ul li'); …my.other_results = KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲some_table td')…my.other_results.css(‘border-color’, ‘red’);
$my.traffic_light.css(‘border-color’, ‘green’);
}
(4)更好的利用链
前面的例子也可以这样写:
1
2
3
4
5
6
7
8
9 var $active_light = $(’#traffic_light input.on’);
$active_light.bind(‘click’, function(){…})
.css(‘border’, ‘3px dashed yellow’)
.css(‘background-color’, ‘orange’)
.fadeIn(‘slow’);
这样可以让我们写更少的代码,使JavaScript更轻量。
(5)使用子查询
jQuery允许我们在一个包集上附加其它的选择器。因为我们已经在本地变量里保存了父对象这样会减少以后在选择器上的性能开销。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(6)限制直接对DOM操作
DOM操作的基本做法是在内存中创建DOM结构,然后再更新DOM结构。这不是jQuery最好的做法,但对JavaScript来讲是高效的。直接操作DOM结构性能是低下的。 例如,如果你需要动态创建一列元素,不要这样做:
?
1
2
3
4
5
6
7
8
9 var top_100_list = […], // assume this has 100 unique strings
$mylist = KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲mylist'); // jQ…mylist.append(’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 var top_100_list = […], // assume this has 100 unique strings
$mylist = $(’#mylist’), // jQuery selects our
(7)事件委托(又名:冒泡事件)
除非特别说明,每一个JavaScript事件(如click, mouseover 等)在DOM结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:
1
2
3
4
5 KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲myList li).bind…(this).addClass(‘clicked’); // do stuff
});
反而,我们应该在父级侦听click事件。
1
2
3
4
5
6
7
8
9
10
11
12
13 KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲myList).bind('c…target = KaTeX parse error: Expected '}', got 'EOF' at end of input: …== 'LI') { target.addClass(‘clicked’); // do stuff
}
});
父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。
(8)消除查询浪费
虽然jQuery对没有找到任何匹配的elements处理的很好,但是它还是需要花费时间去查找的。如果你的站点有一个全局的JavaScript,你可能会把每个jQuery function都放在 $(document).ready(function(){ // all my glorious code })里。 不要这样做。只去放一些页面上适合用到的function。这样做最有效的方式是你的模板可以完全控制任何时候或者地方执行JavaScript以内联脚 本的方式初始化function。例如,在你的“article”页面模板里,你可能在body标签关闭之前包含以下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 var mylib ={
article_page : {
init : function() {
// Article page specific jQuery functions.
}
},
traffic_light : {
init : function() {
// Traffic light specific jQuery functions.
}
}
}
(9)遵从$(windows).load
有 一种诱惑会使jQuery开发者hook所有事情到 ( d o c u m e n t ) . r e a d y 这 个 虚 伪 的 事 件 里 。 毕 竟 在 大 多 数 例 子 里 都 可 以 看 到 这 样 使 用 。 虽 然 (document).ready 这个虚伪的事件里。毕竟在大多数例子里都可以看到这样使用。虽然 (document).ready这个虚伪的事件里。毕竟在大多数例子里都可以看到这样使用。虽然(document).ready 非常有用,它在页面呈现时发生,虽然其它对象还在下载中。如果你发现你的页面在下载中停顿,就有可能是 ( d o c u m e n t ) . r e a d y 引 起 的 。 你 可 以 通 过 把 j Q u e r y f u n c t i o n s 帮 定 到 (document).ready 引起的。你可以通过把jQuery functions帮定到 (document).ready引起的。你可以通过把jQueryfunctions帮定到(window).load事件来减少下面下载时的CPU使用率,它是在所有HTML(包括iframe内容)都下载完以后才 去调用所有对象的。
1
2
3
4
5 $(window).load(function(){
// jQuery functions to initialize after the page has loaded.
});
多余的功能,如拖拽、帮定可视化效果和动画、预读取图片等,使用这种方法比较好。
(10)压缩JS
虽然和jQuery无关,但在这里也要提一下。使JavaScript函数和变量变得可读是一个趋势,这对开发者来讲是必不可少的,但对普通用户来 讲没有任何关系。不用什么借口,是时候把JS压缩纳入我们的工作流程中来了。注释你的代码,在投放到生产环境之前找一个压缩工具进行压缩。使用 YUICompressor 压缩你代码中多余的浪费的字节。根据我们的经验,它可以安全的把JavaScript压缩的尽可能小,而不会多占用CPU。小提示:为了在 YUICompressor里最大化压缩,应该这样这样定义变量(例如:var my_long_variable_name;)
学习和最有效的使用jQuery,最好的方法就是去查jQuery的文档和手册了。
以上就是本文的全部内容,了解更多jQuery的语法,大家可以查看:《jQuery 1.10.3 在线手册》,也希望大家多多支持脚本之家。
91、jQuery和Zepto的区别?各自的使用场景?
(1) Zepto 对象 不能自定义事件
例如执行: $({}).bind(‘cust’, function(){});
结果: TypeError: Object has no method ‘addEventListener’
解决办法是创建一个脱离文档流的节点作为事件对象:
例如: $(’’).bind(‘cust’, function(){});
(2)Zepto 的选择器表达式: [name=value] 中value 必须用 双引号 " or 单引号 ’ 括起来
例如执行:$(’[data-userid=123123123]’)
结果:Error: SyntaxError: DOM Exception 12
解决办法: $(’[data-userid=“123123123]”’) or $("[data-userid=‘123123123’]")
2-1.zepto的选择器没有办法选出 $(“div[name!=‘abc’]”) 的元素
2-2.zepto获取select元素的选中option不能用类似jq的方法 ( ′ o p t i o n [ s e l e c t e d ] ′ ) , 因 为 s e l e c t e d 属 性 不 是 c s s 的 标 准 属 性 应 该 使 用 ('option[selected]'),因为selected属性不是css的标准属性 应该使用 (′option[selected]′),因为selected属性不是css的标准属性 应该使用(‘option’).not(function(){ return !this.selected })
比如:jq: t h i s . f i n d ( ′ o p t i o n [ s e l e c t e d ] ′ ) . a t t r ( ′ d a t a − v ′ ) ∗ 1 z e p t o : this.find('option[selected]').attr('data-v') * 1 zepto: this.find(′option[selected]′).attr(′data−v′)∗1 zepto:this.find(‘option’).not(function() {return !this.selected}).attr(‘data-v’) * 1
但是获取有select中含有disabled属性的元素可以用 $this.find(“option:not(:disabled)”) 因为disabled是标准属性
参考网址:https://github.com/madrobby/zepto/issues/503
2-3、zepto在操作dom的selected和checked属性时尽量使用prop方法,以下是官方说明:
(3)Zepto 是根据标准浏览器写的,所以对于节点尺寸的方法只提供 width() 和 height(),省去了 innerWidth(), innerHeight(),outerWidth(),outerHeight()
Zepto.js: 由盒模型( box-sizing )决定
jQery: 忽略盒模型,始终返回内容区域的宽/高(不包含 padding 、 border )解决方式就是使用 .css(‘width’) 而不是 .width() 。
3-1.边框三角形宽高的获取
假设用下面的 HTML 和 CSS 画了一个小三角形:
[html] view plain copy
1.
3-3.隐藏元素
Zepto.js: 无法获取宽高;
jQuery: 可以获取。
(4)Zepto 的each 方法只能遍历 数组,不能遍历JSON对象
(5)Zepto 的animate 方法参数说明 :详情点击->
zepto中animate的用法
(6)zepto的jsonp callback函数名无法自定义
(7)DOM 操作区别
jq代码:
[html] view plain copy
1.(function(KaTeX parse error: Expected '}', got 'EOF' at end of input: ) { 2. (function() {
3. var l i s t = list = list = (‘
(8)事件触发区别
jq代码:
[html] view plain copy
1.(function(KaTeX parse error: Expected '}', got 'EOF' at end of input: ) { 2. (function() {
3. s c r i p t = script = script = (’
(9)zepto阻止事件冒泡
link传送门
10、zepto的slideUP和slidedown事件到底部才能触发
[html] view plain copy
1.document.addEventListener(‘touchmove’, function (event) {
2.event.preventDefault();
3.}, false);
92、Zepto的点透问题如何解决?
(1)“点透”是什么
你可能碰到过在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹出层后后,这个按钮正下方的内容也会执行点击事件(或打开链接)。这个被定义为这是一个“点透”现象。
在前面的项目中遇到了如下图的问题:在点击弹出来的选择组件的右上角完成后会让完成后面的input输入框聚焦,弹出输入键盘,也就是点透了
(2)为什么会出现点透呢?
这个需要从zepto(或者jqm)源码里面看关于tap的实现方法:
View Code
可以看出zepto的tap通过兼听绑定在document上的touch事件来完成tap事件的模拟的,及tap事件是冒泡到document上触发的
再点击完成时的tap事件(touchstart\touchend)需要冒泡到document上才会触发,而在冒泡到document之前,用户手的接触屏幕(touchstart)和离开屏幕(touchend)是会触发click事件的,因为click事件有延迟触发(这就是为什么移动端不用click而用tap的原因)(大概是300ms,为了实现safari的双击事件的设计),所以在执行完tap事件之后,弹出来的选择组件马上就隐藏了,此时click事件还在延迟的300ms之中,当300ms到来的时候,click到的其实不是完成而是隐藏之后的下方的元素,如果正下方的元素绑定的有click事件此时便会触发,如果没有绑定click事件的话就当没click,但是正下方的是input输入框(或者select选择框或者单选复选框),点击默认聚焦而弹出输入键盘,也就出现了上面的点透现象。
(3)点透的解决方法:
方案一:来得很直接github上有个fastclick可以完美解决https://github.com/ftlabs/fastclick
引入fastclick.js,因为fastclick源码不依赖其他库所以你可以在原生的js前直接加上
1 window.addEventListener( “load”, function() {2 FastClick.attach( document.body );3 }, false );
或者有zepto或者jqm的js里面加上
1 $(function() {2 FastClick.attach(document.body);3 });
当然require的话就这样:
1 var FastClick = require(‘fastclick’);2 FastClick.attach(document.body, options);
方案二:用touchend代替tap事件并阻止掉touchend的默认行为preventDefault()
1 $("#cbFinish").on(“touchend”, function (event) {2 //很多处理比如隐藏什么的3 event.preventDefault();4 });
方案三:延迟一定的时间(300ms+)来处理事件
1 $("#cbFinish").on(“tap”, function (event) {2 setTimeout(function(){3 //很多处理比如隐藏什么的4 },320);5 });
这种方法其实很好,可以和fadeInIn/fadeOut等动画结合使用,可以做出过度效果
理论上上面的方法可以完美的解决tap的点透问题,如果真的倔强到不行,用click
94、如何判断当前脚本运行在浏览器还是node环境中?(阿里)
node环境是一个服务器端js的解释器。
看this指向global还是指向window。
前者是node环境,后者是浏览器。即node全局变量是global,浏览器全局变量是window。
typeof window==“undefined”?global:window;
95、把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?
(1)拉取 HTML 页面 (e.g. index.html)
(2)开始解析 HTML
(3)解析到
96、移动端的点击事件的有延迟,为什么会有?
Google开发者文档中有提到:
mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.
移动浏览器为什么会设置300毫秒的等待时间呢?这与双击缩放的方案有关。平时我们有可能已经注意到了,双击缩放,即用手指在屏幕上快速点击两次,可以看到内容或者图片放大,再次双击,浏览器会将网页缩放至原始比例。
浏览器捕获第一次单击后,会先等待一段时间,如果在这段时间区间里用户未进行下一次点击,则浏览器会做单击事件的处理。如果这段时间里用户进行了第二次单击操作,则浏览器会做双击事件处理。这段时间就是上面提到的300毫秒延迟。
如何避免延迟
在特定场景如一些游戏页面,我们需要取消300毫毛的延迟。目前有以下方法:
方法一:静止缩放
[html] view plain copy
1.
使用这个方法必须完全禁用缩放来达到目的,虽然大部分移动端能解决这个延迟问题,但是部分苹果手机还是不行。
方法二:fastclick.js
FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到touchend事件的时候,会通过 DOM 自定义事件立即触发一个模拟click事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。使用方法如下。
第一步:在页面中引入fastclick.js文件。
第二步:在js文件中添加以下代码
在 window load 事件之后,在body上调用FastClick.attach()即可。
[javascript] view plain copy
1.window.addEventListener(function(){
2. FastClick.attach( document.body );
3.},false );
如果你项目使用了JQuery,就将上面的代码改写成:
[javascript] view plain copy
1.$(function() {
2. FastClick.attach(document.body);
3.});
方法三:指针事件
指针事件最初由微软提出,现已进入 W3C 规范的候选推荐标准阶段 (Candidate Recommendation)。指针事件是一个新的 web 事件系列,相应的规范旨在使用一个单独的事件模型,对所有输入类型,包括鼠标 (mouse)、触摸 (touch)、触控 (stylus) 等,进行统一的处理。
指针事件 (Pointer Events) 目前兼容性不太好,不知道在以后会不会更加支持。
97、知道各种JS框架(Angular, Backbone, Ember, React, Meteor, Knockout…)么? 能讲出他们各自的优点和缺点么?
angular、backbone、knockout都是完整的MV*框架
angular是双向数据绑定的,backbone、knockout是单向数据绑定的
React只是单纯地View层
在认识一切事物之后,人才能认识自己,因为事物仅仅是人的界限。 —— 尼采
Js作用域与作用域链详解
http://blog.csdn.net/yueguanghaidao/article/details/9568071
一直对Js的作用域有点迷糊,今天偶然读到Javascript权威指南,立马被吸引住了,写的真不错。我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫。
一:函数作用域
先看一小段代码:
[javascript] view plaincopy
var scope=“global”;
function t(){
console.log(scope);
var scope=“local”
console.log(scope);
}
t();
(PS: console.log()是firebug提供的调试工具,很好用,有兴趣的童鞋可以用下,比浏览器+alert好用多了)
第一句输出的是: “undefined”,而不是 “global”
第二讲输出的是:“local”
你可能会认为第一句会输出:“global”,因为代码还没执行var scope=“local”,所以肯定会输出“global"。
我说这想法完全没错,只不过用错了对象。我们首先要区分Javascript的函数作用域与我们熟知的C/C++等的块级作用域。
在C/C++中,花括号内中的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的。而Javascript压根没有块级作用域,而是函数作用域.
所谓函数作用域就是说:-》变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
所以根据函数作用域的意思,可以将上述代码重写如下:
[javascript] view plaincopy
var scope=“global”;
function t(){
var scope;
console.log(scope);
scope=“local”
console.log(scope);
}
t();
我们可以看到,由于函数作用域的特性,局部变量在整个函数体始终是由定义的,我们可以将变量声明”提前“到函数体顶部,同时变量初始化还在原来位置。
为什么说Js没有块级作用域呢,有以下代码为证:
[javascript] view plaincopy
var name=“global”;
if(true){
var name=“local”;
console.log(name)
}
console.log(name);
都输出是“local",如果有块级作用域,明显if语句将创建局部变量name,并不会修改全局name,可是没有这样,所以Js没有块级作用域。
现在很好理解为什么会得出那样的结果了。scope声明覆盖了全局的scope,但是还没有赋值,所以输出:”undefined“。
所以下面的代码也就很好理解了。
[javascript] view plaincopy
function t(flag){
if(flag){
var s=“ifscope”;
for(var i=0;i<2;i++)
;
}
console.log(i);
console.log(s);
}
t(true);
输出:2 ”ifscope"
二:变量作用域
还是首先看一段代码:
[javascript] view plaincopy
function t(flag){
if(flag){
s=“ifscope”;
for(var i=0;i<2;i++)
;
}
console.log(i);
}
t(true);
console.log(s);
就是上面的翻版,知识将声明s中的var去掉。
程序会报错还是输出“ifscope"呢?
让我揭开谜底吧,会输出:”ifscope"
这主要是Js中没有用var声明的变量都是全局变量,而且是顶层对象的属性。
所以你用console.log(window.s)也是会输出“ifconfig"
当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说无法通过delete运算符删除
var name=1 ->不可删除
sex=”girl“ ->可删除
this.age=22 ->可删除
三:作用域链
先来看一段代码:
[javascript] view plaincopy
name=“lwy”;
function t(){
var name=“tlwy”;
function s(){
var name=“slwy”;
console.log(name);
}
function ss(){
console.log(name);
}
s();
ss();
}
t();
当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显
name是"slwy"。
但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"
下面看一个很容易犯错的例子:
[html] view plaincopy
四:with语句
说到作用域链,不得不说with语句。with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。
看下面代码
[javascript] view plaincopy
person={name:“yhb”,age:22,height:175,wife:{name:“lwy”,age:21}};
with(person.wife){
console.log(name);
}
with语句将person.wife添加到当前作用域链的头部,所以输出的就是:“lwy".
with语句结束后,作用域链恢复正常。
99、哪些操作会造成内存泄漏?
Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的可能是24M,当我们的内存占用超过了一定的程度后,就会出现OutOfMemory的错误。
下面说明几点可能导致内存泄露的原因,供大家参考。
(1)对象内存过大
保存了多个好用内存过大的对象,造成内存超出限制。
(2)资源释放
程序代码的问题,长期保持某些资源,如Context,Cursor,IO流的引用,资源得不到释放造成内存泄露。
(3)static关键字的使用
static 是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例,就可能会造成内存的泄露。
针对static的解决方案:
应该尽量避免static成员变量引用资源耗费过多的实例,比如Context.
Context尽量使用ApplicationContext的生命周期比较长,引用它不会出现内存泄露。
使用WeakReference代替强引用。比如可以使用WeakReference mContext;
(4).线程导致内存溢出
线程产生内存泄露的主要原因在于线程生命周期的不可控。如当我们切换横竖屏的时候,一般会重新创建Activity,老的Activity应该被销毁。但是此时我们在子线程中正在进行耗时的操作,老的Activity不会被销毁,这个时候就会出现内存泄露。
解决方案:
将线程的内部类,改为静态内部类。
在线程内部采用弱引用保存Context引用。
100、Node.js的适用场景?
NodeJS是近年来比较火的服务端JS平台,这一方面得益于其在后端处理高并发的卓越性能,另一方面在nodeJS平台上的npm、grunt、express等强大的代码与项目管理应用崛起,几乎重新定义了前端的工作方式和流程。
NodeJS的成功标志着它的强大,但是不是所有情况都适合应用NodeJS作为服务器端平台呢?
答案当然是否定的,而网上也是众说纷纭。那我们从原理出发了解一下NodeJS的适用情况。
在讲NodeJS之前我们不仿先看一下传统(以Apache为代表)的服务器端处理平台处理并发的方式。
(1) Apache的多线程高并发模式
Apache是当前世界排名第一的Web服务端软件,它由于支持多线程并发而受到广大服务器技术选型者的欢迎。但发展到后来,Apache在一些WEB的大型应用中也渐渐暴露出它的缺点:阻塞。
那有的同学会奇怪,Apache不是多线程处理并发吗,为什么还会出现阻塞呢?
要明白这一点我们首先需要了解线程这个概念
1.1 什么是线程?
我们引用官方的解释:线程可以独立运行的最小的CPU单位,可以在同一个进程里并发运行,共享该进程下的内存地址空间(注意这个特点)。
我们可以看到同一个进程下的线程是会共享相同的文件和内存的(内存地址空间),所以大家可以想象,当不同的线程需要占用同一个变量时,根据先到先得的原则,先到的线程在运作时,后来的线程只能在旁边等待,也就是加入到了阻塞排队序列。所以这就是造成线程阻塞的原因。
因此,虽说进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,因为程序设计者必须小心,确保它们不会妨碍同一进程里的其它线程。
了解了多线程并行的缺陷后,我们就可以更好地理解NodeJS的强大所在了。因为NodeJS是异步单线程的!
(2) NodeJS的异步I/O原理
我们先来看一段Apache请求数据库的代码:
代码执行到第一行的时候线程会阻塞,等待query返回结果,然后继续处理。由于数据库查询、磁盘读写、网络通信等原因(所谓的I/O)阻塞时间会非常大(相对于CPU始终频率)。对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。看看node.js怎么处理。
看到没,就四个字:异步回调。query的第二个参数是一个回调函数,进程执行到db.query的时候不会等待结果返回,而是直接继续执行下面的语句,直到进入事件循环。当数据库执行结果返回的时候会将事件发送到事件队列,等到线程进入事件循环后才会调用之前的回调函数。更专业的说法是异步I/O。只要单线程就可以。
那为什么NodeJS做到单线程,却可以实现异步呢?在这里我们先上一幅图,直戳图中的Event queue
看到没,NodeJS的工作原理其实就是事件循环。可以说每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的!
看到这里,你不禁会惊叹,NodeJS如果所有处理都异步,岂不是晓得飞了?错错错!当然不是,不要忘记,NodeJS实现这些的基础是单线程。没错,单线程!一条线程扛起所有操作!
你可以想象一下,NodeJS在寒风中面对着10万并发大军,OK,没问题,上来敌人一个扔到城里,上来一个又扔到城里。城里全民皆兵,可以很好地消化这些敌人。但如果上来一个类似于张飞赵云这样的人物,老Node心里一惨,和张飞大战300回合,把他打残了,再扔到城里。那后面的10万大军就得等这300回合。。。
所以这说明什么?说明NodeJS不是没有阻塞,而是阻塞不发生在后续回调的流程,而会发生在NodeJS本身对逻辑的计算和处理。我们已经知道,NodeJS的分发能力无比强大,可以循环事件进行异步回调。但如果在循环事件时遇到复杂的逻辑运算,那么单薄的单线程怎么支撑得起上百万的逻辑+并发呢?NodeJS它的所有I/O、网络通信等比较耗时的操作,都可以交给worker threads执行再回调,所以很快。但CPU的正常操作,它就只能自己抗了。
说到这里,各位对NodeJS的特性估计也大概有个谱了。所以说适用的场景基本是呼之欲出了~!
(3) NodeJS的应用场景
既然NodeJS处理并发的能力强,但处理计算和逻辑的能力反而很弱,因此,如果我们把复杂的逻辑运算都搬到前端(客户端)完成,而NodeJS只需要提供异步I/O,这样就可以实现对高并发的高性能处理。情况就很多啦,比如:RESTFUL API、实时聊天、客户端逻辑强大的单页APP,具体的例子比如说:本地化的在线音乐应用,本地化的在线搜索应用,本地化的在线APP等。
顺便提一下Apache,打压了这么多,给颗甜枣。Apache由于其多线程高并发共享内存地址空间的特性,那就意味着如果服务器足够强大,处理器足够高核,Apache的运作将会非常良好,所以适用于(并发)异步处理相对较少,后台计算量大,后台业务逻辑复杂的应用程序。
101、简述一下 Handlebars 的基本用法?
Handlebars的安装是比较简单和方便的;handlebars是一个纯JS库,因此你可以像使用其他JS脚本一样用script标签来包含handlebars.js
基本
html:
<-- 模板 -->
js:
//获取到模板
var tpl = $("#tpl").html();
//预编译模板
var template = Handlebars.compile(tpl);
//模拟数据(也可以是获取的json数据)
var context = {};
//匹配数据
var html = template(context);
//输入模板
$(‘body’).html(html);
注 : 这是handlebars最常用的一中创建使用模式。
102、用js实现千位分隔符?
输入:数字(考虑数字是否合法、正负号、小数点)、字符串
输出:考虑到使用场景,最好是字符串
测试用例:-1234567.9012
期待输出:-1,234,567.9012
千位分隔符貌似在《精通正则表达式》中讲环视的时候作为经典范例,然而写出来发现js不支持逆序环视,也就是 (?<=expression) (? // 正则function thousandBitSeparator(num) {
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+.)/g, function($0, $1) {
return $1 + “,”;
});}console.log(thousandBitSeparator(-1234567.9012));// -1,234,567.9012
todo
当测试用例是1000的时候,此正则不能正确标注千位分隔符,现修改如下:
function thousandBitSeparator(num) {
return num && (num
.toString().indexOf(’.’) != -1 ? num.toString().replace(/(\d)(?=(\d{3})+.)/g, function($0, $1) {
return $1 + “,”;
}) : num.toString().replace(/(\d)(?=(\d{3}))/g, function($0, $1) {
return $1 + “,”;
}));}console.log(thousandBitSeparator(1000));//1,000
103、检测浏览器版本版本有哪些方式?
如何判断浏览器的类型和版本? – 使用JavaScript的内置对象 navigator 的属性userAgent的值来判断(navigator.userAgent)。
navigator是javascript的内置对象,通常用于检测浏览器与操作系统的版本。 常用的属性有
appCodeName – 浏览器代码名的字符串表示
appName – 官方浏览器名的字符串表示
appVersion – 浏览器版本信息的字符串表示
cookieEnabled – 如果启用cookie返回true,否则返回false
javaEnabled – 如果启用java返回true,否则返回false
platform – 浏览器所在计算机平台的字符串表示
plugins – 安装在浏览器中的插件数组
taintEnabled – 如果启用了数据污点返回true,否则返回false
userAgent – 用户代理头的字符串表示(就是包含浏览器版本信息等的字符串)
104、我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,你来说下会执行几次事件,然后会先执行冒泡还是捕获
事件的执行顺序绝对是让人头疼的问题。当父元素与子元素都绑定了多个事件,且有的绑定在冒泡阶段、有的绑定在捕获阶段时,事件的触发顺序如何?如果你只关心这个问题,请直接下滑到3. 绑定多个事件,且由用户行为触发。如果你想细致了解JavaScript中的事件发生,请慢慢阅读。
(1) 原生事件的发生顺序
一般来讲,当为一个a标签添加click事件以后,点击这个标签,会先执行绑定的事件、后跳转页面。一个input绑定blur事件以后,你在input里输入完内容,点击提交按钮,会先发生blur事件,后发生click事件。当然,这是一般来讲。我在一个React项目中曾经发生表单提交时,先发生click事件,blur事件没有来得及发生,造成表单内容没有检验就提交到后台,原因我至今没有找到,解决办法是在click事件上加一个50ms的延迟。
(2)自定义事件
JavaScript中也支持手动触发事件,请看下面代码。
a.addEventListener(‘click’, function(){
console.log(input.value);
console.log(this.getAttribute(‘href’));
console.log(location.href);
}, false); //a是我已经通过id获得好的一个a标签
var event = document.createEvent('HTMLEvents'); // initEvent接受3个参数: 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent('click', true, true);
event.eventType = 'click';
//触发a上绑定的自定义事件
a.dispatchEvent(event); //注:jQuery中有更简单的trigger()方法实现自定义事件功能
JavaScript中自定义事件的类型有(即document.createEvent(‘HTMLEvents’)中的参数):
UIEvents:一般化的UI事件。
MouseEvents:一般化的鼠标事件。
MutationEvents:一般化的DOM变动事件。
HTMLEvents:一般化的HTML事件。
自定义事件的发生比较容易控制,你什么时候触发(dispatchEvent/fireEvent)它,它就什么时候发生。
(3)绑定多个事件,且由用户行为触发
这个情况最复杂,也是标题中的情况:父元素与子元素都绑定多个事件,且有的事件在捕获阶段、有的事件在冒泡阶段。
下面这个例子,父元素div绑定两个事件(一个冒泡阶段、一个捕获阶段),子元素也是这种情况。事件触发顺序如何。
var btn = document.querySelector(‘button’);
var div = document.querySelector(‘div’);
btn.addEventListener('click', function(){
console.log('bubble','btn');
},false);
btn.addEventListener('click', function(){
console.log('capture','btn');
},true);
div.addEventListener('click', function(){
console.log('bubble','div');
},false);
div.addEventListener('click', function(){
console.log('capture','div');
},true);
执行结果:
乍一看这个结果有些乱,但仔细分析可以得出结论:
绑定在被点击元素的事件是按照代码顺序发生,其他元素通过冒泡或者捕获“感知”的事件,按照W3C的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。
105、设计模式 知道什么是singleton, factory, strategy, decrator么?
设计模式主要分三个类型:创建型、结构型和行为型。
其中创建型有:
一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
行为型有:
六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
十、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系
十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
十四、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。
十五、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
十六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
结构型有:
十七、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。
十八、Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。
十九、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问
二十、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
二十一、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。
二十二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
二十三、Flyweight,享元模式
106、常使用的库有哪些?
使用率较高的框架有jQuery、YUI、Prototype、Dojo、Ext.js、Mootools等。
107、列举IE与其他浏览器不一样的特性?
事件不同之处:
触发事件的元素被认为是目标(target)。而在 IE 中,目标包含在 event 对象的 srcElement 属性;
获取字符代码、如果按键代表一个字符(shift、ctrl、alt除外),IE 的 keyCode 会返回字符代码(Unicode),DOM 中按键的代码和字符是分离的,要获取字符代码,需要使用 charCode 属性;
阻止某个事件的默认行为,IE 中阻止某个事件的默认行为,必须将 returnValue 属性设置为 false,Mozilla 中,需要调用 preventDefault() 方法;
停止事件冒泡,IE 中阻止事件进一步冒泡,需要设置 cancelBubble 为 true,Mozzilla 中,需要调用 stopPropagation();
108、WEB应用从服务器主动推送Data到客户端有那些方式?
html5提供的Websocket
不可见的iframe
WebSocket通过Flash
XHR长时间连接
XHR Multipart Streaming