前端知识点总结(JavaScript篇)
- 同源策略及跨域请求的方法和原理(比较JSONP和document.domain的不同及优劣,以及HTML5的跨域方案)
- JavaScript数据类型
- JavaScript字符串转化
- JSONP原理及优缺点
- XMLHttpRequest
- 事件委托
- 前端模块化(AMD和CommonJS的原理及异同,seajs和requirejs的异同和用法)
- session
- Cookie
- seaJS的用法及原理,依赖加载的原理、初始化、实现等
- this问题
- 模块化原理(作用域)
- JavaScript动画算法
- 拖拽的实现
- JavaScript原型链及JavaScript如何实现继承、类的
- 闭包及闭包的用处,以及闭包可能造成的不良后果。
- 常见算法的JS实现(如快排、冒泡等)
- 事件冒泡和事件捕获
- 浏览器检测(能力检测、怪癖检测等)
- JavaScript代码测试
- call与apply的作用及不同
- bind的用法,以及如何实现bind的函数和需要注意的点
- 变量名提升
- == 与 ===
- "use strict"作用
- AJAX请求的细节和原理
- 函数柯里化(Currying)
- NodeJS健壮性方面的实践(子进程等)
- NodeJS能否用利用多核实现在计算性能上的劣势等
- jQuery链式调用的原理
- ES6及jQuery新引进的Promise有什么用处、Promise的原理
- NodeJS的优缺点及使用场景
- JS中random的概率问题
- 客户端存储及他们的异同(例如:cookie, sessionStorage和localStorage等)
- AngularJS的文件管理及打包(包括模板打包及请求、JS的打包和请求等)
- AngularJS的JS模块管理及实践
- 在你的Angular App页面里随意加一个JS文件,会有什么影响
- AngularJS directive及自己如何定义directive
- AngularJS双向绑定的原理及实现
- 你如何测试你的JS代码
- DOM1\DOM2\DOM3都有什么不同
- XSS
- 常用数组方法和数组算法(如数组去重、求交集、并集等)
- js数组去重复项
- js中的垃圾回收机制
- 常见的JS设计模式
- js获取服务器精准时间(客户端如何与服务器时间同步)
- 什么是js中的类数组对象
- Node中exports和module.exports的区别
- 异步编程的了解
- Grunt和Gulp的区别
- AngularJS中service\factory\provider的区别
- JavaScript中异步编程的几种方式
- Nodejs开发踩过的坑
- AngularJS中依赖注入的理解
- JS中判断是否为数组
- Nodejs内存溢出
- 关于BFC和hasLayout
- 统计页面中使用最多的三个标签
- JS内存泄露及解决方法
- 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
- 判断两个对象的相等
- 选取两个数的最大公约数
- Node模块是如何寻址的
- ES6新增的特性
escape()
,decodeURIComponent()
,decodeURI
之间的区别是什么?- CSRF?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
同源策略及跨域请求的方法和原理(比较JSONP和document.domain的不同及优劣,以及HTML5的跨域方案)
答案:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。这里的同源指的是:同协议,同域名和同端口。这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
浏览器的同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。有一点需要说明,不同的框架之间(父子或同辈),是能够获取到彼此的window对象的,但头疼的是你却不能使用获取到的window对象的属性和方法(html5中的postMessage方法是一个例外,还有些浏览器比如ie6也可以使用top、parent等少数几个属性),总之,你可以当做是只能获取到一个几乎无用的window对象。document.domain:只要将同一域下不同子域的document.domain设置为共同的父域,则这个时候我们就可以访问对应window的各种属性和方法了。例如:www.example.com父域下的www.lib.example.com和www.hr.example.com两个子域,将对应页面的document.domain设为example.com即可。缺点:只能在一级域名相同时才能运用。
JSONP:原理是动态添加一个script标签,而script标签的src属性是没有跨域的限制的。jquery中还提供了一个$.getJSON(url,arg,callback(data))用来进行jsonp访问。缺点:只支持get不支持post;只支持http请求这种情况,不能解决不同域两个页面之间如何进行JavaScript调用的问题;JSONP请求失败时不返回http状态码。
CORS(跨域资源共享):HTML5引入的新的跨域的方法,不过需要在请求头和相应头设置相应的Access-Control-属性。缺点:兼容性问题,适合一些新的浏览器。
参考:
说说JSON和JSONP
js中几种实用的跨域方法原理详解
The Same Origin Policy: JSONP vs The document.domain Property
HTTP访问控制(CORS) -
JavaScript数据类型
答案: JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。 -
JavaScript字符串转化
答案:熟悉基本的字符串操作函数,参考
JavaScript中常见的字符串操作函数及用法 -
JSONP原理及优缺点
答案:具体JSONP的原理可参考1,说白了就是插入一个script标签,其src指向跨域接口,返回对应的callback(data),其中data是json格式,callback是页面已存在的function。
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。 -
XMLHttpRequest
答案:轻松掌握XMLHttpRequest对象 -
事件委托
答案:使用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。 -
前端模块化(AMD和CommonJS的原理及异同,seajs和requirejs的异同和用法
答案:
使用AMD\CommonJS\ES Harmony编写模块化的JavaScript
RequireJS中文网SeaJS对模块的态度是懒执行,SeaJS只会在真正需要使用(依赖)模块时才执行该模块;而RequireJS对模块的态度是预执行;会先尽早地执行(依赖)模块, 相当于所有的require都被提前了, 而且模块执行的顺序也不一定
SeaJS和RequireJS最大的不同,其中AMD和CMD的区别可以看玉伯在知乎上的回答 -
session
-
常见的cookie操作包括创建cookie、添加cookie、删除cookie等,相应函数参考:
//添加(daysToLive大于0)cookie/删除(daysToLive为0)cookie function setcookie(name,value,daysToLive){ var cookie = name + "=" + encodeURIComponent(value); if(typeof daysToLive === "number"){ cookie += ";max-age=" + (daysToLive*60*60*24); } document.cookie = cookie; } //解析cookie,直接getcookie()[name]获取对应的name cookie function getcookie(){ var cookies = {}; var all = document.cookie; if(all === ""){ return false; } var list = all.split(";"); for(var i=0;i < list.length; i++){ var cookie = list[i]; var p = cookie.indexOf("="); var name = cookie.substring(0,p); var value = cookie.substring(p+1); value = decodeURIComponent(value); cookies[name] = value; } return cookies; } //删除某个cookie function deletecookie( name ) { document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; //或者 document.cookie = name + '=; expires=' + (new Date(1970)).toGMTString(); }
-
seaJS的用法及原理,依赖加载的原理、初始化、实现等
答案:模块化开发之sea.js实现原理总结,简言之就是要解决三个问题,分别为:
1.模块加载(插入script标签来加载模块。你在页面看不到标签是因为模块被加载完后删除了对应的script标签);
2.模块依赖(按依赖顺序依赖);
3.命名冲突(封装一层define,所有的都成为了局部变量,并通过exports暴漏出去)。 -
this问题
答案:别再为了this发愁了------JS中的this机制 -
模块化原理(作用域)
答案:其中seajs的原理参考第10题。大致原理都类似。 -
JavaScript动画算法
-
拖拽的实现
-
JavaScript原型链及JavaScript如何实现继承、类的
答案:原型链:就是每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针(prototype),而实例则包含一个指向原型对象的内部指针(proto),通过将子构造函数的原型指向父构造函数的实例。
参考:
JS 面向对象之继承 -- 原型链
js 基于原型的类实现详解 -
闭包及闭包的用处,以及闭包可能造成的不良后果
答案:好处:能够实现封装和缓存等;坏处:就是消耗内存、不正当使用会造成内存溢出的问题。
聊一下JS中的作用域scope和闭包closure
javascript 闭包的好处及坏处 -
常见算法的JS实现(如快排、冒泡等)
答案:常用排序算法之JavaScript实现。这里有一篇阮一峰老师写的,非常不错的快排算法,快速排序(Quicksort)的Javascript实现。
和排序算法. 还有如《五大常用算法》等。 -
事件冒泡和事件捕获
答案:W3C中定义事件的发生经历三个阶段:捕获阶段(capturing)、目标阶段(targeting)、冒泡阶段(bubbling)。
阻止事件传播的方法:ie下:window.event.cancelBubble = true; 其他浏览器:e.stopPropagation()。
参考:
事件冒泡和事件捕获 -
浏览器检测(能力检测、怪癖检测等)
-
JavaScript代码测试
答案:平时在测试方面做的比较少,一般用JSlint检查一些常见的错误。对于功能性的可能会使用基于karma+Jasmine测试框架来做。 -
call与apply的作用及不同
答案:作用是绑定this指针,设定函数中this的上下文环境。第二个参数不同,apply是类数组,而call是一些列参数。 -
bind的用法,以及如何实现bind的函数和需要注意的点
答案:bind的作用与call和apply相同,区别是call和apply是立即调用函数,而bind是返回了一个函数,需要调用的时候再执行。
一个简单的bind函数实现如下:Function.prototype.bind = function(ctx) { var fn = this; return function() { fn.apply(ctx, arguments); }; };
可参考:How is bind() different from call() & apply() in Javascript?
-
变量名提升
答案:参考16中的博客及评论部分。 -
== 与 ===
答案:前者隐式类型转换,后者严格对比。 -
"use strict"作用
答案:作用是为了规范js代码,消除一些不合理、不严谨的地方;提高效率;为以后新版本js做铺垫。
主要限制:
1.全局变量显式声明;
2.禁止使用with,不推荐使用eval;
3.增强安全措施,比如禁止this关键字指向全局对象;
4.禁止删除变量;
5.显式报错;比如对只读属性赋值,对一个使用getter方法读取属性赋值,对禁止扩展的对象添加新属性;
6.重名错误,对象不能有重名的属性,函数不能有重名的参数;
7.禁止八进制表示法;
8.argument对象的限制;比如禁止使用arguments.callee;
9.函数必须声明在顶层;
10.新增保留字:implements, interface, let, package, private, protected, public, static, yield -
AJAX请求的细节和原理
答案:原生的细节也需要重点研究,其实是jQuery ajax -
函数柯里化(Currying)
答案: 柯里化(Currying),是把接受多个参数的函数变换为接受单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
作用:
1.参数复用;在柯里化的外围函数中添加复用的参数即可。
2.提前返回;参看“参考”中绑定事件的例子。
3.延迟计算/运行;其实Function.prototype.bind的方法中延迟计算就是运用的柯里化。
参考:
JS中的柯里化(currying) -
NodeJS健壮性方面的实践(子进程等)
答案:同29。
-
NodeJS能否用利用多核实现在计算性能上的劣势等
-
jQuery链式调用的原理
-
ES6及jQuery新引进的Promise有什么用处、Promise的原理
-
NodeJS的优缺点及使用场景
-
JS中random的概率问题
-
客户端存储及他们的异同(例如:cookie, sessionStorage和localStorage等)
共同点:都是保存在浏览器端,且同源的。
区别:
1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
2.cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
3.存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,一般为5M左右。
4.数据有效期不同,sessionStorage仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage始终有效(除非清除),窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
5.作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
6.Web Storage 支持事件通知机制(storage事件),可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。 -
AngularJS的文件管理及打包(包括模板打包及请求、JS的打包和请求等)
-
AngularJS的JS模块管理及实践
-
在你的Angular App页面里随意加一个JS文件,会有什么影响
答案:这个啥问题XX。
-
AngularJS directive及自己如何定义directive
-
AngularJS双向绑定的原理及实现
答案:AngularJS数据绑定及AngularJS的工作机制,参考《AngularJS up and running》第203页,十三章第一节。简单说检查数据有无更新,仅在以下事件发生时,即:XHR请求、页面加载、用户交互事件等。
-
你如何测试你的JS代码
答案:平时在测试方面做的比较少,一般用JSlint检查一些常见的错误。对于功能性的可能会使用基于karma的Jasmine测试框架来做。
-
DOM1\DOM2\DOM3都有什么不同
-
XSS
答案:1. 《浅谈javascript函数劫持》 2. 《xss零碎指南》
-
常用数组方法和数组算法(如数组去重、求交集、并集等)
答案:javascript常用数组算法总结和Merge/flatten an Array of Arrays in JavaScript
-
js数组去重复项
-
js中的垃圾回收机制
-
常见的JS设计模式
-
js获取服务器精准时间(客户端如何与服务器时间同步)
答案:思路:简而言之就是发送一个ajax请求,然后获取对应的HTTP Header中的time,由于时延等问题造成时间在JS客户端获取后当前时间已经不再是服务器此时的时间,然后用本地的时间减去获取的服务器的时间,这应该就是时间偏移量。再新建一个时间,加上此偏移量应该就是此时此刻服务器的时间。代码如下:
var offset = 0; function calcOffset() { var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); xmlhttp.open("GET", "http://stackoverflow.com/", false); xmlhttp.send(); var dateStr = xmlhttp.getResponseHeader('Date'); var serverTimeMillisGMT = Date.parse(new Date(Date.parse(dateStr)).toUTCString()); var localMillisUTC = Date.parse(new Date().toUTCString()); offset = serverTimeMillisGMT - localMillisUTC; } function getServerTime() { var date = new Date(); date.setTime(date.getTime() + offset); return date; }
或者是:
var start = (new Date()).getTime(); var serverTime;//服务器时间 $.ajax({ url:"XXXX", success: function(data,statusText,res){ var delay = (new Date()).getTime() - start; serverTime = new Date(res.getResponseHeader('Date')).getTime() + delay; console.log(new Date(serverTime));//标准时间 console.log((new Date(serverTime)).toTimeString());//转换为时间字符串 console.log(serverTime);//服务器时间毫秒数 } })
-
什么是js中的类数组对象
答案:1、它们都有一个合法的 length 属性(0 到 2**32 - 1 之间的正整数)。2、length 属性的值大于它们的最大索引(index)。
-
Node中exports和module.exports的区别
-
异步编程的了解
答案:
-
Grunt和Gulp的区别
-
AngularJS中service\factory\provider的区别
答案:讲的非常不错,可以看看。Differences Between Providers In AngularJS和stackoverflow上的回答Service vs provider vs factory。如果英文看的不爽,这里有一篇中文的,还不错那伤不起的provider们啊。
-
JavaScript中异步编程的几种方式
答案:参加阮一峰前辈写的Javascript异步编程的4种方法,简单说就是1回调函数2事件监听3发布/订阅4promise
-
Nodejs开发踩过的坑
-
AngularJS中依赖注入的理解
-
JS中判断是否为数组
答案:isArray/typeof/instanceof,还有toString方法返回的字符串(数组返回'[Object Array]')。
-
Nodejs内存溢出
-
关于BFC和hasLayout
-
统计页面中使用最多的三个标签
答案:思路大致是首先获取页面中所有用到的标签数组,然后依次遍历,将用到的标签放置新的hash表里,每次检测到相同标签对应的key的value值加1.最后转为数组,排序,取前三个。实现方法如下:
function findTags(){ var allTags = document.getElementsByTagName("*"), hash = {}; for(var i = 0, j = allTags.length; i < j; i++){ var temp = allTags[i].tagName; if(hash[temp]){ hash[temp]++; }else{ hash[temp] = 1; } } var sortable = []; for (var i in hash){ sortable.push([i, hash[i]]); } sortable.sort(function(a, b) {return b[1] - a[1]}); return sortable.splice(0,3); }
-
JS内存泄露及解决方法
答案:JS内存泄露及解决方法
-
在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
-
判断两个对象的相等
-
选取两个数的最大公约数
-
Node模块是如何寻址的
答案:《NodeJS深入浅出》模块开发那一章有详解。
-
ES6新增的特性
答案:
-
escape()
,decodeURIComponent()
,decodeURI
之间的区别是什么?
答案:- 传递参数时需要使用encodeURIComponent,这样组合的url才不会被#等特殊字符截断。
- 进行url跳转时可以整体使用encodeURI
- js使用数据时可以使用escape
- escape对0-255以外的unicode值进行编码时输出%u****格式,其它情况下escape,encodeURI,encodeURIComponent编码结果相同。
另外: - escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z
- encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z
- encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z
-
CSRF?
答案:浅谈CSRF攻击方式