<script type="text/javascript">
$(function () {
/**
1.变量的作用域
闭包: 函数内定义的任何变量 或者函数,包裹它们的外层函数提供一个沙箱环境, 俗称闭包.
一般该函数体以外 都无法访问这些变量 或者函数
局部变量: 一般把函数内定义的任何变量,称之局部变量,作用域限于该函数内.
全局变量: 放在一个Js文件或者在script标签最外层,jq最外层的变量
*/
//在jq全局变量, 可以在任何位置访问
let myLibrary = {
myName: "Chris Lu"
};
function doSomething(){
//局部变量: 函数体内定义的变量
let innerVar = 1234;
//全局变量可以在函数中访问
myLibrary.myName = "Hello, Lu";
function elseSomething() {
//外层函数定义局部变量, 能在内层函数访问到
console.log(innerVar);
}
elseSomething();
}
//调用函数
doSomething();
//函数内部覆盖了 全局变量myLibrary.myName属性
console.log(myLibrary.myName);
//在函数外层 不能访问该函数的局部变量
/**
* 2.js闭包
* 匿名函数作为fn的返回值被赋值给了fn1,这时候相当于fn1=function(){var n = 0 … },并且匿名函数内部引用着fn里的变量num,
* 所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次fn1执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题
*/
function fn() {
let num = 3;
return function () {
let n = 0;
console.log("n:",++n);
console.log("num:",++num);
}
}
let fn1 = fn();
//闭包产生内存消耗, 调用过程中, 外层函数局部变量内存无法被释放
fn1(); //n: 1, num: 4
fn1(); //n: 1, num: 5
/**
* 定时器与闭包
* 1.定时器内部 按顺序打印出当前循环次数
* for循环变量 使用let定义就可以解决
* 2.每隔100毫秒分别依次输出数字
*/
for (let i = 0; i < 5; i++) {
setTimeout(function () {
//console.log("i=",i);
},100);
}
//没隔1000毫秒输出数字
for (let j = 0; j < 5; j++) {
(function (j) {
setTimeout(function () {
console.log("j=",j)
},j*2000);
})(j)
}
/**
3.上下文this关键字
1).在普通函数之外this, script标签内this指代window, 在jq包裹内this指代document.
2). fn2()函数在没有对象包裹情况下, this指向 全局对象window; 放在对象包裹中话, this指向该对象
*/
console.log("this指代document:",this === document);
function fn2() {
console.log("fn2的this",this === window);
}
fn2();
/**
* 对象中this指向: 对象中简单函数, this就是指向对象本身.
*/
let house = {
floors: 2,
isLocked: false,
lock: function () {
console.log("简单函数this:",this===house); //true,this指向包裹该函数的对象
//可以把this看做house的替身
this.isLocked = true;
}
};
house.lock();
console.log("isLocked通过this改变:",house.isLocked);
/**
* 对象中的嵌套函数,this指向的是包裹该对象的外层全局window对象
* 想绕过该陷阱, 对象中函数嵌套, 一般将this的值保存在一个变量中, 利用该变量来代替this -- that变量
*/
let apartment = {
isLocked: false,
lock: function () {
let that = this;
//设置isLocked属性
this.isLocked = true;
function fn3() {
console.log("this是否指向apartment:",this===apartment); //false
console.log("this是否指向document:",this===window); //true
console.log("that是否指向apartment:",that===apartment); //true
//通过that修改apartment对象isLocked属性
that.isLocked = false;
}
fn3();
}
};
apartment.lock();
console.log("apartment属性isLocked:",apartment.isLocked); //false
});
console.log("this指代window:",this === window);
</script>
网友评论