7种!javascript
其中,除了Object是引用类型外,都是基本类型css
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------html
null是一个空指针,是一个特殊的object,会被前端
undefined是指一个被调用但未被赋值的变量html5
他们在if条件下都为falsejava
null 转为数字是0,而undefined转为数字是NaNwebpack
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ios
一、标记清除nginx
二、引用计数git
对于性能问题:若是在运行期间,分配的内存不少,那么垃圾收集的工做量也会至关大,所以,每一次垃圾收集的时间间隔如何肯定是一个很重要的问题。
从IE7开始,js改变了垃圾收集的工做方式:触发垃圾收集的变量分配。相似于TCP拥塞窗口的控制。。。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
先捕获,再冒泡
如上图所示,你点击了一个div里的text,会先从window捕获,直到text,而后从text冒泡,一直到冒泡到window
那么什么是捕获,什么是冒泡?
好比:
element.addEventListener('click', function(e){
console.log(e.target)
}, true|false);
其中,咱们经常使用的false就是冒泡,true就是捕获。
return不只阻止事件冒泡,也阻止事件自己,stopPropagation()只阻止事件冒泡
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{} === {} // false [] === [] // false (function () {} === function () {}) // false
上面代码分别比较两个空对象、两个空数组、两个空函数,结果都是不相等。
缘由是对于复合类型的值,严格相等运算比较的是,它们是否引用同一个内存地址,而运算符两边的空对象、空数组、空函数的值,都存放在不一样的内存地址,结果固然是。
false
注意:NaN与任何值都不相等,包括自身。
NaN === NaN // false
a !== b 等价于
!(a === b)
1 == true // true // 等同于 1 === Number(true) 0 == false // true // 等同于 0 === Number(false) 2 == true // false // 等同于 2 === Number(true) 2 == false // false // 等同于 2 === Number(false) 'true' == true // false // 等同于 Number('true') === Number(true) // 等同于 NaN === 1 '' == 0 // true // 等同于 Number('') === 0 // 等同于 0 === 0 '' == false // true // 等同于 Number('') === Number(false) // 等同于 0 === 0 '1' == true // true // 等同于 Number('1') === Number(true) // 等同于 1 === 1 '\n 123 \t' == 123 // true // 由于字符串转为数字时,省略前置和后置的空格
// 对象与数值比较时,对象转为数值 [1] == 1 // true // 等同于 Number([1]) == 1 // 对象与字符串比较时,对象转为字符串 [1] == '1' // true // 等同于 String([1]) == '1' [1, 2] == '1,2' // true // 等同于 String([1, 2]) == '1,2' // 对象与布尔值比较时,两边都转为数值 [1] == true // true // 等同于 Number([1]) == Number(true) [2] == true // false // 等同于 Number([2]) == Number(true)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ajax
全称是异步 javascript 和 XML
,用来和服务端进行数据交互的,让无刷新替换页面数据成了可能。
https://www.html5rocks.com/zh/tutorials/file/xhr2/#toc-examples
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
这个东西,细节不少,短期内想要基本熟悉很难。
let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText); } } xhr.open(); xhr.send();
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
let add = (function () { let i = 0; return function () { return ++i; } })()
能够这样理解这个闭包,add函数return的是一个匿名函数,所以,访问不到函数内的全局变量i,所以i被隐藏起来了。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
for(var i=0;i<10;i++) { setTimeout((function (x) { return function () { console.log(x) } })(i), 1000) }
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
其中,function meili () {}是函数声明,会有函数声明提高,全局可用。
function mogu () {}是函数表达式,必须先声明,后使用。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 - 2 - 3 - be - also - 4 - test。
https://blog.csdn.net/cjgeng88/article/details/79846670
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
我通常用这三种,cors
,nginx反向代理
,jsonp
jsonp
: 单纯的 get 一些数据,局限性很大...就是利用script标签的src属性来实现跨域。nginx 反向代理
: 主要就是用了nginx.conf
内的proxy_pass http://xxx.xxx.xxx
,会把全部请求代理到那个域名,有利也有弊吧..cors
的话,可控性较强,须要先后端都设置,兼容性 IE10+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CSRF工具的防护手段
1. 尽可能使用POST,限制GET
GET接口太容易被拿来作CSRF攻击,看第一个示例就知道,只要构造一个img标签,而img标签又是不能过滤的数据。接口最好限制为POST使用,GET则无效,下降攻击风险。
固然POST并非万无一失,攻击者只要构造一个form就能够,但须要在第三方页面作,这样就增长暴露的可能性。
2. 浏览器Cookie策略
IE六、七、八、Safari会默认拦截第三方本地Cookie(Third-party Cookie)的发送。可是Firefox二、三、Opera、Chrome、Android等不会拦截,因此经过浏览器Cookie策略来防护CSRF攻击不靠谱,只能说是下降了风险。
PS:Cookie分为两种,Session Cookie(在浏览器关闭后,就会失效,保存到内存里),Third-party Cookie(即只有到了Exprie时间后才会失效的Cookie,这种Cookie会保存到本地)。
PS:另外若是网站返回HTTP头包含P3P Header,那么将容许浏览器发送第三方Cookie。
3. 加验证码
验证码,强制用户必须与应用进行交互,才能完成最终请求。在一般状况下,验证码能很好遏制CSRF攻击。可是出于用户体验考虑,网站不能给全部的操做都加上验证码。所以验证码只能做为一种辅助手段,不能做为主要解决方案。
4. Referer Check
Referer Check在Web最多见的应用就是“防止图片盗链”。同理,Referer Check也能够被用于检查请求是否来自合法的“源”(Referer值是不是指定页面,或者网站的域),若是都不是,那么就很可能是CSRF攻击。
可是由于服务器并非何时都能取到Referer,因此也没法做为CSRF防护的主要手段。可是用Referer Check来监控CSRF攻击的发生,却是一种可行的方法。
5. Anti CSRF Token
如今业界对CSRF的防护,一致的作法是使用一个Token(Anti CSRF Token)。
例子:
1. 用户访问某个表单页面。
2. 服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。
3. 在页面表单附带上Token参数。
4. 用户提交请求后, 服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。
这个Token的值必须是随机的,不可预测的。因为Token的存在,攻击者没法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token时应注意Token的保密性,尽可能把敏感操做由GET改成POST,以form或AJAX形式提交,避免Token泄露。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------cookie
,sessionStorage
,localStorage
的差别..cookie
: 大小4KB 左右,跟随请求(请求头),会占用带宽资源,可是如果用来判断用户是否在线这些挺方便sessionStorage
和localStorage
大同小异,大小看浏览器支持,通常为5MB,数据只保留在本地,不参与服务端交互.
sessionStorage
的生存周期只限于会话中,关闭了储存的数据就没了.localStorage
则保留在本地,没有人为清除会一直保留-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
https://www.cnblogs.com/lvdabao/p/es6-promise-1.html
let p = new Promise(function(resolve, reject) { setTimeout(function () { console.log('执行完成'); resolve('hello'); }, 2000); });
我new了一个Promise对象,先无论这里面的每句话是什么意思,这里注意,在new的同时,里面的函数已经被执行了,所以咱们能够利用函数,让Promise延迟执行。
function dosomethingAsync () { let p = new Promise(function(resolve, reject) { setTimeout(function () { console.log('执行完成'); resolve('hello'); }, 2000); }); return p; } dosomethingAsync();
这里说一个概念,promise的状态,promise的状态分为三种,pending(等待),fulfilled(成功),rejected(失败)。一个promise只能从pending到另外两种状态之一转变,且这种转变是单向的,一次性的。也就是说,只能转变一次,且不可更改结果。
那么要怎么转变呢?就经过resolve(),和reject()。
好比咱们定义,咱们从数据库取年龄为100岁的人的信息,若是取到了,就是成功,若是没取到就是失败,咱们写一下伪代码
1 function getSomeoneInfo () { 2 let p = new Promise(function (resolve, reject) { 3 axios.get('http://获取年龄的api/&age=100', function (response) { 4 // 接收响应的回调函数 5 if (response.data 不为空) { 6 // 成功了 7 resolve(response.data); 8 } else { 9 // 失败了 10 reject('error'); 11 } 12 }) 13 }) 14 return p; 15 } 16 17 getSomeoneInfo ();
能够看到,Promise在尚未执行的时候状态为pending,在经过resolve和reject函数后分别转为两种对应的状态。
那么知道状态改变了之后,要怎么作呢?经过then
function getSomeoneInfo () { let p = new Promise(function (resolve, reject) { axios.get('http://获取年龄的api/&age=100', function (response) { // 接收响应的回调函数 if (response.data 不为空) { // 成功了 resolve(response.data); } else { // 失败了 reject('error'); } }) }) return p; } getSomeoneInfo().then(function (data) { console.log(data); }, function (data) { console.log(data); });
能够看到then函数的参数是两个匿名函数,能够这么理解,用then来监听promise的状态变化,若是转向成功,就执行第一个函数,且参数data 和 response.data一致,不然转向第二个函数,data等于'error'。
promise.all()
同时执行多个异步函数,所有都执行完了,进到then里
Promise .all([runAsync1(), runAsync2(), runAsync3()]) .then(function(results){ console.log(results); });
result是三个函数执行结果组成的数组。
promise.race()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
https://segmentfault.com/a/1190000013292562?utm_source=channel-newest
放在一个函数前的async有两个做用:
promise前面的await关键字可以使JavaScript等待,直到promise处理结束。而后:
若是它是一个错误,异常就产生了,就像在那个地方调用了throw error同样。
有了async/await,咱们不多须要写promise.then/catch,可是咱们仍然不该该忘记它们是基于promise的,由于有些时候(例如在最外面的范围内)咱们不得不使用这些方法。Promise.all也是一个很是棒的东西,它可以同时等待不少任务。
举例
一个获取头像的需求,若是用promise只能以链式这么写,若是不以promise写,甚至会形成回调地狱
loadJson('/article/promise-chaining/user.json') .then(user => loadGithubUser(user.name)) .then(showAvatar) .then(githubUser => alert(`Finished showing ${githubUser.name}`));
若是用async / await
async function showAvatar() { // read our JSON let response = await fetch('/article/promise-chaining/user.json') let user = await response.json() // read github user let githubResponse = await fetch(`https://api.github.com/users/${user.name}`) let githubUser = await githubResponse.json() // 展现头像 let img = document.createElement('img') img.src = githubUser.avatar_url img.className = 'promise-avatar-example' documenmt.body.append(img) // 等待3s await new Promise((resolve, reject) => { setTimeout(resolve, 3000) }) img.remove() return githubUser } showAvatar()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
new 操做符新建了一个空对象,这个对象原型指向构造函数的prototype,执行构造函数后返回这个对象。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
clientHeight:表示的是可视区域的高度,不包含border和滚动条
offsetHeight:表示可视区域的高度,包含了border和滚动条
scrollHeight:表示了全部区域的高度,包含了由于滚动被隐藏的部分。
clientTop:表示边框border的厚度,在未指定的状况下通常为0
scrollTop:滚动后被隐藏的高度,获取对象相对于由offsetParent属性指定的父坐标(css定位的元素或body元素)距离顶端的高度。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http://www.cnblogs.com/coco1s/p/5499469.html
针对高频度触发的事件(例如页面 scroll ,屏幕 resize,监听用户输入等)应该减小操做,下面介绍两种经常使用的解决方法,防抖和节流。
函数节流是指必定时间内js方法只跑一次。好比人的眨眼睛,就是必定时间内眨一次。这是函数节流最形象的解释。
函数防抖是指频繁触发的状况下,只在最终中止的时候,才执行代码一次。好比生活中的坐公交,就是必定时间内,若是有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
前端模块化就是复杂的文件编程一个一个独立的模块,好比js文件等等,分红独立的模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,因此有了commonJS规范,AMD,CMD规范等等,以及用于js打包(编译等处理)的工具webpack。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一个模块是能实现特定功能的文件,有了模块就能够方便的使用别人的代码,想要什么功能就能加载什么模块。
requireJS实现了AMD规范,主要用于解决下述两个问题。
1.多个文件有依赖关系,被依赖的文件须要早于依赖它的文件加载到浏览器 2.加载的时候浏览器会中止页面渲染,加载文件越多,页面失去响应的时间越长。
语法:requireJS定义了一个函数define,它是全局变量,用来定义模块。
requireJS的例子:
//定义模块 define(['dependency'], function(){ var name = 'Byron'; function printName(){ console.log(name); } return { printName: printName }; }); //加载模块 require(['myModule'], function (my){ my.printName(); }
requirejs定义了一个函数define,它是全局变量,用来定义模块:
define(id?dependencies?,factory)
在页面上使用模块加载函数:
require([dependencies],factory);
总结AMD规范:require()函数在加载依赖函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块加载成功,才会去执行。
由于网页在加载js的时候会中止渲染,所以咱们能够经过异步的方式去加载js,而若是须要依赖某些,也是异步去依赖,依赖后再执行某些方法。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function deepClone(obj){ var newObj= obj instanceof Array ? []:{}; for(var item in obj){ var temple= typeof obj[item] == 'object' ? deepClone(obj[item]):obj[item]; newObj[item] = temple; } return newObj; }
ES5的经常使用的对象克隆的一种方式。注意数组是对象,可是跟对象又有必定区别,因此咱们一开始判断了一些类型,决定newObj是对象仍是数组~
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var myNewAjax=function(url){ return new Promise(function(resolve,reject){ var xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(data); xhr.onreadystatechange=function(){ if(xhr.status==200&&readyState==4){ var json=JSON.parse(xhr.responseText); resolve(json) }else if(xhr.readyState==4&&xhr.status!=200){ reject('error'); } } }) }
http://www.javashuo.com/article/p-qasukviu-dp.html
value:对应的值,默认为undefined。
writable:是否能够被重写。默认为false。用内部方法也不可被修改
enumeable:此属性是否能够被枚举到(注意这个说法,“被枚举到”,当你用for in或object.keys()的时候能不能被枚举出来)。设置为true能够被枚举;设置为false,不能被枚举。默认为false。
configurable:是否能够删除目标属性或是否能够再次修改属性的特性(writable, configurable, enumerable)。设置为true能够被删除或能够从新设置特性;设置为false,不能被能够被删除或不能够从新设置特性。默认为false。
咱们假设这里有一个user对象,
Object.defineProperty(user,'name',{ set:function(key,value){ } })
缺点:若是id不在user对象中,则不能监听id的变化
var user = new Proxy({},{ set:function(target,key,value,receiver){ } })
这样即便有属性在user中不存在,经过user.id来定义也一样能够这样监听这个属性的变化哦~
obj={ name:yuxiaoliang, getName:function(){ return this.name } } object.defineProperty(obj,"name",{ //不可枚举不可配置 });
function product(){ var name='yuxiaoliang'; this.getName=function(){ return name; } } var obj=new product();
==
:等同,比较运算符,两边值类型不一样的时候,先进行类型转换,再比较;===
:恒等,严格比较运算符,不作类型转换,类型不一样就是不等;Object.is()
是ES6新增的用来比较两个值是否严格相等的方法,与===
的行为基本一致。先说= = =
,这个比较简单,只须要利用下面的规则来判断两个值是否恒等就好了:
isNaN()
或Object.is()
来判断)。再说Object.is()
,其行为与===
基本一致,不过有两处不一样:
举个栗子☺:
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true
这里有一篇文章讲的是requestAnimationFrame:http://www.cnblogs.com/xiaohuochai/p/5777186.html
与setTimeout和setInterval不一样,requestAnimationFrame不须要设置时间间隔,
大多数电脑显示器的刷新频率是60Hz,大概至关于每秒钟重绘60次。大多数浏览器都会对重绘操做加以限制,不超过显示器的重绘频率,由于即便超过那个频率用户体验也不会有提高。所以,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms。
RAF采用的是系统时间间隔,不会由于前面的任务,不会影响RAF,可是若是前面的任务多的话,
会响应setTimeout和setInterval真正运行时的时间间隔。
特色:
(1)requestAnimationFrame会把每一帧中的全部DOM操做集中起来,在一次重绘或回流中就完成,而且重绘或回流的时间间隔牢牢跟随浏览器的刷新频率。
(2)在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这固然就意味着更少的CPU、GPU和内存使用量
(3)requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,而且若是页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。