这篇文章是由于以前看过一篇文章,总结了一些技能,可是并不详细,以后陆续还会有新的文章。javascript
js中有两种事件,DOM0和DOM2.html
document.getElementById('click').onclick = function(){ console.log('123') }
解除绑定很简单,赋值为null便可。java
document.getElementById('click').onclick = null
可是这种事件虽然在全部浏览器都能运行,可是有个很明显的缺陷,就是不能绑定多个相同事件,若是绑定了多个相同事件,后面的会覆盖前面的jquery
其实js中的声明提高很简单,就是指变量声明提高和函数的声明提高。声明提示的意思就是把变量或者函数在编译的时候提高到环境的顶部,并赋值undefinednginx
变量声明,js会把变量声明分为两个部分,一个是声明操做(var a),一个是赋值操做(a=1),这里的声明提高针对的是声明操做,赋值操做仍是在原来的地方等待执行。web
定义函数的方式有两种,函数声明和函数表达式,函数表达式和变量声明同等。
在js编译时,函数声明会把函数声明和整个函数体都提高到环境的顶部,因此能够在函数声明前调用这个函数,如如下代码ajax
foo() function foo(){ console.log(111) }
函数声明是优先于变量声明的
1.js编译时,会把全部的函数声明提到顶部,若是有重复的进行覆盖
2.把全部的变量提到顶部,并赋值undefined,若是有重复的进行覆盖
接下来看两个典型的例子json
alert(a) a(); var a=3; function a(){ alert(10) } alert(a) a=6; a(); ------------分割线------------------ alert(a) a(); var a=3; var a=function(){ alert(10) } alert(a) a=6; a();
第一部分:
1.函数声明优先于变量声明,因此,刚开始,a就是function a(){alert(10)} ,就会看到这个函数。
2.a(),执行函数,就是出现alert(10)
3.执行了var a=3; 因此alert(a)就是显示3
4.因为a不是一个函数了,因此往下在执行到a()的时候, 报错。
第二部分运行结果:
1.underfind
2.报错
在以前说过,预解析是把带有var和function关键字的事先声明,但不会赋值。因此一开始是underfind,而后报错是由于执行到a()的时候,a并非一个函数。api
js继承的几种方法
1.原型链继承,将父类的实例做为子类的原型跨域
function Cat(){} Cat.prototype = New Animal()
2.构造继承,利用父元素的构造函数来加强子元素的实例,其实就是把父类的实例属性给了子类
function Cat(){ Animal.call(this); }
3.实例继承,父类的实例增长属性做为子类的实例返回
function Cat(){ var instance = new Animal(); intance.name = 'aaa'; return instance; }
4.拷贝继承,没法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom'; }
5.组合继承,经过调用父类,实现了继承父类的属性和保留传参的优势,父类的实例做为子类的原型,实现了函数的复用
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;//组合继承也是须要修复构造函数指向的。
6.寄生组合继承,经过第三方的一个空类,来继承父类的函数复用,父类的属性的继承经过在子类中调用父类实现。
/** * 通用方法实现子类继承父类 * @param {function} child 子类构造函数 * @param {function} father 被继承的父类构造函数 */ function inheritPrototype(child, father) { var prototype = object(father.prototype); //建立一个指定原型的对象 prototype.constructor = child; //加强对象 child.prototype = prototype; //子类的原型等于该对象 } function father(name) { this.faName = 'father'; } father.prototype.getfaName = function() { console.log(this.faName); }; function child(args) { this.chName = 'child'; father.apply(this,[]); } inheritPrototype(child, father); //子类的原型等于new 空函数(), 而new 空函数()出来的对象的原型等于父类的原型 child.prototype.getchName = function() { console.log(this.chName); }; console.log( child.prototype.isPrototypeOf(new child()) ); //true console.log(new child() instanceof child); //true
优势:1.只调用一次父类的构造函数,避免了在子类原型上建立没必要要的,多余的属性
2.原型链保持不变
https://blog.csdn.net/xuqingg...
参考https://www.cnblogs.com/humin...
跨域,是指不能执行其余网站的脚本,是由于浏览器的同源策略(域名,协议,端口均相同)引发的,是浏览器对js实施的安全限制。可是script标签自己就能够访问其它域的资源,不受浏览器同源策略的限制,能够经过在页面动态建立script标签。
限制:
1.cookie,localstorage,indexDB没法读取
2.DOM和js对象没法获取
3.ajax请求发不出去
解决办法:
1.jsonp 可是只限于get请求
1.1 经过动态建立script标签,请求一个带参数的网址实现跨域
var script = document.createElement('script'); script.src = 'http://www.aaa.com/username=aaaa&callback=cb'; document.body.appendChild(script); function cb(res){}
1.2 jquery的ajax支持jsonp
$.ajax({ url:'http://www.aaa.com', type:'get', dataType:'json', jsonCallback:'cb', data:{ username:'111' } })
2.document.domain+iframe,可是要求主域名相同
3.window.name + iframe 跨域
4.location.hash + iframe 跨域
5.postMessage
1.html
<iframe id="iframe" src="http://www.neal.cn/b.html" style="display:none;"></iframe> <script> var iframe = document.getElementById('iframe'); iframe.onload = function() { var data = { name: 'aym' }; // 向neal传送跨域数据 iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.neal.cn'); }; // 接受domain2返回数据 window.addEventListener('message', function(e) { alert('data from neal ---> ' + e.data); }, false); </script>
2.html(另外一端口)
script> // 接收domain1的数据 window.addEventListener('message', function(e) { alert('data from nealyang ---> ' + e.data); var data = JSON.parse(e.data); if (data) { data.number = 16; // 处理后再发回nealyang window.parent.postMessage(JSON.stringify(data), 'http://www.nealyang.cn'); } }, false); </script>
6.跨域资源共享CORS
CORS是目前主流的跨域解决方案。
它容许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了ajax的同源策略的限制。
目前全部的浏览器都支持这个功能。IE要求IE10以上,IE8,9须要用XDomainRequest对象来支持这个功能。
CORS须要客户端和服务端同时支持。
整个CORS通讯过程,都是浏览器完成的,对于开发者来讲,CORS和ajax没有什么区别,发送请求后,浏览器识别到这是跨源请求,就会在头部添加附加信息,有时还会多一次请求。因此实现CORS的关键是服务器,只要服务器实现了CORS接口,就能够跨源通讯。
这时候就要说到请求的种类了,分为简单请求和非简单请求。
简单请求
简单请求(请求方式为HEAD,GET,POST,头信息不超过如下字段,Accept,Accept-language,Content-language,Last-Event-ID,Content-type【application/x-www-form-urlencoded、multipart/form-data、text/plain】)。
浏览器直接发出CORS请求,在头信息中会增长origin属性(origin:http://www.baidu.com),这个属性代表请求的来源,服务器根据这个是否赞成此次请求。若是origin指定的源不在许可范围内,服务端会返回http回应,浏览器会发现没有Access-Control-Allow-Origin字段,就会抛出异常,到XMLHttpRequest的onerror函数。
若是Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段
上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头
withCredentials 属性
上面说到,CORS请求默认不发送Cookie和HTTP认证信息。若是要把Cookie发到服务器,一方面要服务器赞成,指定Access-Control-Allow-Credentials字段。
另外一方面,开发者必须在AJAX请求中打开withCredentials属性。
不然,即便服务器赞成发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。
可是,若是省略withCredentials设置,有的浏览器仍是会一块儿发送Cookie。这时,能够显式关闭withCredentials。
须要注意的是,若是要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其余域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也没法读取服务器域名下的Cookie。
非简单请求
非简单请求是那种对服务器有特殊要求的请求,好比请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通讯以前,增长一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可使用哪些HTTP动词和头信息字段。只有获得确定答复,浏览器才会发出正式的XMLHttpRequest请求,不然就报错。
var url = 'http://api.alice.com/cors'; var xhr = new XMLHttpRequest(); xhr.open('PUT', url, true); xhr.setRequestHeader('X-Custom-Header', 'value'); xhr.send();
浏览器发现,这是一个非简单请求,就自动发出一个"预检"请求,要求服务器确承认以这样请求。下面是这个"预检"请求的HTTP头信息。
OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪一个源。
除了Origin字段,"预检"请求的头信息包括两个特殊字段。
预检请求的回应
服务器收到"预检"请求之后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段之后,确认容许跨源请求,就能够作出回应.
上面的HTTP回应中,关键的是Access-Control-Allow-Origin字段,表示http://api.bob.com能够请求数据。该字段也能够设为星号,表示赞成任意跨源请求。
若是浏览器否认了"预检"请求,会返回一个正常的HTTP回应,可是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不一样意预检请求,所以触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。控制台会打印出报错信息。
服务器回应的其余CORS相关字段以下:
Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000
浏览器正常请求回应
一旦服务器经过了"预检"请求,之后每次浏览器正常的CORS请求,就都跟简单请求同样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。7.websocket8.nginx