闭包与ajax
1.匿名函数
(1)之前学过的函数
//1.普通
function sum(){
console.log("Fd");
}
//2.表达式函数
var s = function () {
console.log("fd");
}
//3.事件处理函数
document.onclick = function () {
console.log(this);
}
//4.构造函数
function Student() {
this.name = "web";
}
(2)匿名函数:没有名字的函数
function (){
console.log("匿名函数");
}
//匿名函数自执行
*/IFE:Imdiately Invoked Function Expression 立即执行函数*/
*/优点:
1.避免全局污染,减少不必要的内存浪费
2.方便嵌入
3.放在js最上面,所有的js代码都放进去,避免全局污染,减少内存浪费
*/
//1.自执行
(function () {
console.log("立即执行");
})();//立即执行
//2.自执行函数有参数
(function (a,b) {
console.log(a+b);
})(10,20);//30
//3.返回值
var s = (function (a,b) {
return a+b;
})(10,20);
console.log(s);//30
2.闭包(函数套函数)
闭包就是能够读取其他函数内部变量的函数(函数里面套函数,内部函数访问外部函数变量),在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
*/闭包的特点:
闭包中使用的变量会一直存储在内存中,类似全局变量 ,避免全局污
*/
*/document有一个类似垃圾场的东西,当定义一个局部变量时,如果下面不在有人使用那么就回收释放内存,如果有人使用就一直存在着*/
//1.闭包
function fun(){
var c = 10;
return function(){
console.log(c++);//这个函数里的c自己没有c变量,就得上自己上一级找,所以C一直都不会回收,直到闭包释放,这个c不再被使用,c变量才会被回收
}
}
var f = fun(); //f = function(){ console.log(c++); }
f();//10
f();//11
f();//12
f=null;//释放闭包
//2.闭包解决的问题
for(var i = 0;i<oBut.length;i++){
(function (i) { //参数i
oBut[i].onclick = function () {
for(var j = 0;j<oDiv.length;j++){
oDiv[j].className = "";
}
oDiv[i].className = "active";
}
})(i)//实参i for循环的i
}
*/解决全局变量i,带来的影响*/
3.闭包的经典面试题
1.写出函数运行结果,并写出解决方法
var arr = [];
for(var i = 0;i<10;i++){ //i = 10
arr.push(function(){
console.log(i);
});
}
arr[5](); //10
原因:arr=[function(){console.log(i)},function(){console.log(i)},function(){console.log(i)},function(){console.log(i)}.........]一共十个
调用下标为5这个位置的函数 i=10,我们知道循环很快,当循环的时候,我们并没有调用函数,所以i一直循环到10,当我们调用函数的时候,循环早就结束了循环不会重新再循环一次,所以无论是调用哪个下标下的函数,i都等于10。
解决:
var arr1 = [];
for(var i = 0;i<10;i++){ //i = 10
(function (i) {//将i变成局部变量自己用自己的
arr1.push(function(){
console.log(i);
});
})(i)//for循环的i,没循环一次函数都会立即循环一次,将i的值添加到arr数组里
}
arr1[5]();//5
2.运行下面程序的结果
function fun(n,o){
console.log(o); //闭包
return {
fun:function(m){
return fun(m,n);
}
}
}
var a = fun(0);
a.fun(1);//0
a.fun(2);//0
a.fun(3);//0
*/a是当第一个参数为0的时候调用fun函数的结果,
a={
fun:function(m){
return fun(m,n)
}
}
这时候n=0,o=undefined,因为只有一个参数传入
a相当于json对象,a.fun(1)=function(1){
return fun(1,n);
}
fun(1,n) console.log(o); o=n=0;
*/
3.下面代码的执行结果
for (var i = 0; i < 4; i++) {
setTimeout(function() {
console.log(i);
}, 0); //定时器异步,只要是定时器不管时间是多少,都会放到最后去执行
} //4次4
4.用闭包的形式完成下面代码的修改,使得属性user,id外界不可见
var User = function(){};
User.prototype = {
id:"120",
getId:function(){ return this.id},
setId:function(id){ this.id = id}
}
var s = new User();
console.log(s);

修改:
var User = function(){
var id = "";
this.__proto__ = {
getId:function(){ return id},
setId:function(i){ id = i}
}
};
var s = new User();
console.log(s);
s.setId("007");
console.log(s.getId())
4.什么是ajax?
AJAX即“Asynchronous Javascript And XML”(异步javaScript和XML),是指一种创建交互式网页应用的网页开发技术,可以用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
==同步:==客户端与服务器请求数据的过程中,不能做其他的事情
==异步:==客户端与服务器请求数据的过程中,可以做其他的事情
5.ajax的使用
*/步骤:
1.创建请求对象
2.建立连接
3.发送请求
4.监听结果
*/
(1)get请求
//1.创建请求对象
var ajax = new XMLHttpRequest();
//http:超文本传输协议 Request:请求
//new ActiveXObject("Microsoft.XMLHTTP"); ie6创建
//2.建立连接 ajax.open(method,url,async); method:GET POST
ajax.open("get","wenben.txt?count=2",true);
//3.发送请求
ajax.send();
//4.监听处理情况
ajax.onreadystatechange = function () {
if(ajax.readyState == 4){ //有结果了
if(ajax.status == 200){
console.log(ajax.response);
}
}
}
(2)post请求
//1.创建ajax请求对象
var ajax = new XMLHttpRequest();
//var ajax = new ActiveXObject("Microsoft.XMLHTTP")
//2.建立连接
ajax.open("POST","wenben.txt"); //userName=123&passWord
//3.设置请求头,编码方式,告诉服务器提交数据的类型
ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=uft-8");
//4.发送请求
ajax.send("userName=ujiuye&passWord=123");//data
//5.监听
ajax.onreadystatechange = function () {
if(ajax.readyState == 4){
if(ajax.status == 200){
console.log(eval(ajax.response));
}
}
}
*/Content-type
multipart/form-data:上传有文件时
application/x-www-form-urlencoded:表单 默认
text/plain:文本
*/
*/readyState状态
0:创建了对象
1:建立连接
2:发送了请求
3:接收到了这个请求,并且已经开始处理,没有处理完成
4:已经处理完成,并且返回了响应包
*/
*/Status:网络状态码
200----请求成功
404----没有找到
*/
*/了解
1XX系列:指定客户端应相应的某些动作,代表请求已被接受,需要继续处理。由于HTTP/1.0 协议中没有定义任何 1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送 1xx 响应。
2XX系列:代表请求已成功被服务器接收、理解、并接受。这系列中最常见的有200、201状态码。
3XX系列:代表需要客户端采取进一步的操作才能完成请求,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location 域中指明。这系列中最常见的有301、302状态码。
4XX系列:表示请求错误。代表了客户端看起来可能发生了错误,妨碍了服务器的处理。常见有:401、404状态码。
5XX系列:代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。常见有500、503状态码。
*/
6.封装ajax
/*
* ajax请求
* @param {string}:method 请求方式 get post
* @param {string}:url 请求地址
* @param {function}:fun 回调函数
* @param {string}}:data 请求参数
*/
function ajax(method,url,fun,data){
//1.创建请求对象
var request = new XMLHttpRequest();
//2.建立连接 ,判断 get GET
if(method.toUpperCase() == "GET"){ //get url?wd=a&count=10
url = data ? url +"?" + data : url; //如果data有值,拼接到url中,没有值直接使用
request.open("get",url,true);
request.send();
}else{ //post
request.open("post",url,true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send(data);
}
//4.监听结果
request.onreadystatechange = function(){
if(request.readyState == 4){
if(request.status == 200){
//回调函数
//fun(eval("("+request.responseText+")"));
fun(JSON.parse(request.responseText)); //JSON.parse 将json类型的字符串转化为真正的json数据
}
}
}
}
7.解析json
//eval() : 计算某个字符串,并且执行里面的js代码
console.log(eval("1+2"));
console.log(eval(res)); //报错 eval('{"name":"er"}') js中如果是{}开头,默认是块
console.log(eval("("+res+")"));
//JSON.parse() 将字符串json转换为json类型
console.log(JSON.parse(res));
//JSON.stringify(): 将json转换为字符串json
var obj = {"name":"er"};
console.log(JSON.stringify(obj));
}
}
}