Ajax
- 什么是Ajax:Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下能够更新部分网页的技术
一个完整的HTTP请求过程
- 建立TCP连接
- Web浏览器向Web服务器发送请求命令
- Web浏览器发送请求头信息
- Web服务器应答
- Web服务器发送应答头信息
- Web服务器向浏览器发送数据
- Web服务器关闭TCP连接
HTTP状态码
- 1XX:信息类,表示收到Web浏览器请求,正在进一步的处理中
- 2XX:成功,表示用户请求被正确接收,理解和处理。 200-OK
- 3XX:重定向,表示请求没有成功,客户必须采取进一步的动作
- 4XX:客户端错误,表示客户端提交的请求有错误。 400-NOT Found
- 5XX:服务器错误,表示服务器不能完成对请求的处理。 500
readyState属性(表示请求响应过程的当前活动阶段,只要值发生变化都会触发一次
onreadystatechange
事件)- 0:未初始化。尚未调用
open()
方法 - 1:启动。已经调用
open()
方法,但尚未调用send()
方法 - 2:发送。已经调用
send()
方法,但尚未接收到响应 - 3:接收。已经接收到部分响应数据
- 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了
- 0:未初始化。尚未调用
封装
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455// 请求参数序列化,把对象转换为‘name1=value1&name2=value2’的格式function serialize(data) {if (!data) {return '';}var pairs = [];for (var name in data) {if (!data.hasOwnProperty(name)) {continue;}if (typeof data[name] === 'function') {contunue;}var value = data[name].toString();name = encodeURIComponent(name);value = encodeURIComponent(value);pairs.push(name + '=' + value);}return pairs.join('&')}// get请求function get(url, options, callback) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function() {if (xhr.readyState == 4) {if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {callback(xhr.responseText);} else {console.log('Requeset was unsuccessful: ' + xhr.status);}}}var URL = url + serialize(options); // 如果url后没有问号,还应该加个?xhr.open('GET', URL, true);xhr.setRequestHeader('myHeader', 'myValue'); // 可以省略xhr.send(null);// post请求function post(url, options, callback) {var xhr = new XMLHttpRequest();xhr.onreadystatechange = function() {if (xhr.readyState == 4) {if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {callback(xhr.reponseText);} else {console.log('Requeset was unsuccessful: ' + xhr.status);}}}xhr.open('POST', url, true);xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xhr.send(serialize(options));}}jQuery中的Ajax
- $.ajax([settings]) 这里的[settings]以对象的形式进行设置
- type:类型,“POST”或“GET”,默认为“GET”
- url:发送请求的地址
- data:是一个对象,连同请求发送到服务器的数据
- dataType:预期服务器返回的数据类型。如果不知道,jQuery将自动根据HTTP包MIME信息来智能判断,采用json格式的话可以设置为“json”
- success:是一个方法,请求成功后的回调函数。传入返回后的数据、以及包含成功代码的字符串
- error:是一个方法,请求失败时调用此函数。传入XMLHttpRequest对象
关于跨域
- 当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域;不同域之间相互请求资源,就算作跨域
- 因为JavaScript同源策略的限制,a.com域名下的js无法操作b.com或是c.a.com域名下的对象
- 处理跨域方式
- JSONP:通过动态
<script>
元素来使用,为src
属性指定一个跨域URL,只支持GET请求。 - XMLHttpRequest Level2:IE10以下不支持
- JSONP:通过动态
参考资料
Ajax全接触
this的指向
作为对象的方法调用:this指向该对象
123456789var obj = {a: 1,getA: function() {console.log(this === obj);console.log(this.a);}};obj.getA(); // 分别输出true和1作为普通函数调用:this指向全局对象,在浏览器里即window对象;在
use strict
模式下,this
会绑定到undefined
123456789101112window.name = 'globalName';var myObj = {name: 'whiskey',getName: function() {return this.name;}};var a = myObj.getName;var b = myObj.getName();console.log(a()); // "globalName" 作为普通函数调用console.log(b); // "whiskey" 作为对象的方法调用构造器调用
通常情况下构造器里的this指向返回的这个对象
12345var MyClass = function() {this.name = 'whiskey';};var obj = new MyClass();console.log(obj.name); // 输出"whiskey"如果构造器显示地返回了一个object类型的对象,那么运算结果会返回这个对象,而不是之前的
this
12345678var MyClass = function() {this.name = 'whiskey';return {name: 'lily' // 显示返回一个对象};};var obj = new MyClass();console.log(obj.name); // 输出"lily"
Function.prototype.call 或 Function.prototype.apply调用:可以动态改变传入函数的this
123456789101112131415161718192021222324var obj1 = {name: 'whiskey',getName: function() {return this.name;}};var obj2 = {name: 'lily'};console.log(obj1.getName()); // whiskeyconsole.log(obj1.getName.call(obj2)); // lily// 如果把null、undefined作为this的绑定对象传入,this会指向windowfunction foo() {console.log(this.a);}var a = 2;foo.call(null); // 2,如果把上面的var a = 2注释掉,会得到undefined
比较undefined和null
undefined
(表示“没有值”)- 未初始化的变量是
undefined
- 缺失的参数是
undefined
- 访问不存在的属性,返回
undefined
- 函数中没有显示返回值,函数会隐式返回
undefined
- 未初始化的变量是
null
(表示“没有对象”,将属性或者元素设置为空)null
是原型链最顶端的元素- 当字符串中没有匹配到正则表达式的结果时,
RegExp.prototype.exec()
返回null
闭包
闭包指有权访问另一个函数作用域中变量的函数;利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部
- 解决循环问题 在线demo12345<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div>
|
|
外部访问函数内部定义的变量
12345678910function sayHi() {var name = 'whiskey';var say = function() {console.log('hi, ' + name);};return say;}// say(); // 报错, say is not definedvar sayName = sayHi();sayName(); // 'hi, whiskey'封装
123456789101112131415function countNum(initial) {var num = initial || 0;return {inc: function() {num += 1;return num;}};}var c1 = countNum();console.log(c1.inc()); //1 第一次调用console.log(c1.inc()); //2 第二次调用var c2 = countNum(10);console.log(c2.inc()); // 11console.log(c2.inc()); // 12多参函数变单参函数
123456789function sum(x) {return function(y) {return x + y;};};var addSum = sum(1);console.log(addSum(1)); //2var addSum2 = sum(10);console.log(addSum2(10)); //20
call和apply
- 如果传入的第一个参数为
null
,函数体内的this
会指向默认的宿主对象,浏览器即window - 区别:
apply
接收的第二个参数是个集合,可以是数组或者类数组; 用途
改变
this
指向1234567891011121314151617var obj1 = {name: 'whiskey',};var obj2 = {name: 'lily'};var getName = function() {console.log(this.name);};window.name = 'window';getName(); // 输出windowgetName.call(obj1); // 输出whiskeygetName.call(obj2); // 输出lily借用其他对象的方法
// 实例一 var A = function(name, age) { this.name = name; this.age = age; }; var B = function() { A.apply(this, arguments); // B得到了A的所有属性 }; B.prototype.say = function() { return this.name + ' is ' + this.age + ' years old'; }; var b = new B('whiskey', 20); console.log(b.say()); // "whiskey is 20 years old" // 实例二 var maxNum = Math.max.apply(null, [1, 2, 3, 4, 5]); console.log(maxNum); // 5 // 实例三 var a = {}; Array.prototype.push.call(a, 'first', '语文'); console.log(a[0]); // first console.log(a[1]); // 语文