继承
原型链继承
function Animal() {
this.type = "animal";
this.eat = function (food) {
console.log(food);
};
}
function Cat(name, color) {
this.name = name;
this.color;
}
Cat.prototype = new Animal();
var c1 = new Cat("lily", "white");
var c2 = new Cat("niki", "black");
console.log(c1.type);
c1.eat("鱼");
构造函数继承
/*******************构造函数继承************************ */
function Animal() {
this.type = "动物";
}
function Cat(name, color) {
this.name = name;
this.color = color;
Animal.apply(this); //相当于将Animal和Cat强行关联起来
}
var c1 = new Cat("lily", "white"); //{name: 'lily', color: 'white', type: '动物'}
var c2 = new Cat("niki", "black"); //{name: 'niki', color: 'black', type: '动物'}
c1.__proto__.type = "c1";
console.log(c1.type); //动物
console.log(c2.type); //动物
组合继承
function Animal() {
this.type = "动物";
}
Animal.prototype.eat = function () {
console.log("吃");
};
function Cat(name, color) {
this.name = name;
this.color = color;
Animal.call(this);
}
Cat.prototype = new Animal(); //Cat.prototype的原型对象继承了Animal的对象,
// 通过这一关系,可以把Animal的原型对象也关联到Cat上了
var c1 = new Cat("lily", "white");
var c2 = new Cat("niki", "black");
c1.type = "c1";
c2.__proto__.type = "c2";
console.log(c1.type); //c1
console.log(c2.type); //"动物"
console.log(c2.__proto__.type);
c2.__proto__.eat();
闭包
要理解闭包,首先要理解javascript的全局变量和局部变量
javascript语言的特别之处就在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部 的局部变量
闭包就是能够读取其他函数内部变量的函数
由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在 一个函数内部的函数“
所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁
变量特色:全局变量维持变量状态,局部变量不会造成污染【随着方法执行完而被销毁】
为什么需要闭包?
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。
总结:局部变量无法共享和长久的保存,而全局变量可能造成变量污染,当我们希望有一种机制既可以长久的保存变量又不会造成全局污染,这就是闭包诞生的原因。
变量a只有在没有任何引用指向它时才会被垃圾回收
function f1() {
var a = 20;
function f2() {
a++;
console.log(a);
}
return f2;
}
var f = f1(); //获取到的是f2--function,
console.log(typeof f);
//f1执行的结果是闭包,在闭包里能够维护局部变量的状态
f1()();//这种写法不是闭包,不能维持局部变量的状态,每次执行的结果都是21
//闭包形成的条件:1、返回一个函数;2、这个函数对局部变量存在引用,这样就形成闭包了
//闭包的省略写法
function f1() {
var a = 20;
return function () {
a++;
console.log(a);
};
}
var x = f1();
var y = f1();
x(); //21
x(); //22
x(); //23
y(); //21 一个闭包对变量的修改,不会影响另外一个闭包的变量
闭包实例2
function fn() {
var name = "xp";
return {
getName: function () {
return name;
},
setName: function (newName) {
name = newName;
},
};
}
var o = fn();//返回对象
var name = o.getName();
console.log(name);
o.setName("xupeng");
console.log(o.getName());
利用闭包封装http
function http() {
var xmlhttp = new XMLHttpRequest();
var _url = "http://localhost:3333";
return {
//success:为回调函数
request: function ({ method, url, data, success }) {
xmlhttp.open(method, `${_url}${url}`);
xmlhttp.setRequestHeader("Content-Type", "application/json");
if (method == "GET") {
xmlhttp.send();
} else {
xmlhttp.send(data);
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
success(xmlhttp.responseText);
} else {
//失败的回调
}
};
},
};
}
window.onload = function () {
document.querySelector(".login").onclick = function () {
var _mobile = document.querySelector(".mobile").value;
var _password = document.querySelector(".password").value;
se;
};
function sendData(mobile, password) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://localhost:3333/form_login");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(
JSON.stringify({
mobile: mobile,
password: password,
})
);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log(xmlhttp.responseText);
}
};
}
/************使用闭包封装的http请求***************************** */
var http = http();
function sendDataBB(mobile, password) {
http.request({
method: "POST",
url: "/form_login",
data: JSON.stringify({
mobile: mobile,
password: password,
}),
success: function (res) {
console.log(res);
},
});
}
};