> 文档中心 > js BOM DOM部分基础知识学习笔记(3)

js BOM DOM部分基础知识学习笔记(3)


JavaScript_this关键字

目录

JavaScript_this关键字

事件中的this

对象中的this

JavaScript_函数_闭包概念

变量作用

 如何从外部读取局部变量

闭包的概念

JavaScript_闭包特点

变量的值始终保持在内存中

使用闭包的注意点

JavaScript_闭包应用场景

JavaScript_闭包中的this关键字


事件中的this

监听函数内部的this指向触发事件的那个元素节点

// HTML 代码如下// var btn = document.getElementById('btn');// 写法一btn.onclick = function () {  console.log(this.id);};// 写法二btn.addEventListener('click',function (e) {    console.log(this.id);},false);

对象中的this

永远指向调用者,而难的就是你是否可以找到调用者

var username = 'sxt';var user = {    username:"itbaizhan",    getName:function(){ console.log(username);//username == window.username console.log(this.username);//相当于user.username    }}user.getName();//sxt itbaizhan

JavaScript_函数_闭包概念

闭包(closure)是 Javascript 语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现

理解闭包,首先必须理解变量作用域

变量的作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域

变量的作用域无非就是两种

  1. 全局变量
  2. 局部变量
var n = 100;function getNum(){    console.log(n);}getNum(); // 100

另一方面,在函数外部自然无法读取函数内的局部变量

function getNum(){    var n = 100;    num = 10;//没有添加var 就变成了全局作用域}console.log(n); // errorconsole.log(num); // 10

温馨提示

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量

 如何从外部读取局部变量

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现

那就是在函数的内部,再定义一个函数

function getNum(){    var n = 100;    function getN(){ alert(n); // 100    }}
//全局作用域if(true){    var age = 10;}//在js中以完整的函数作为作用域分割点

既然getN可以读取getNum中的局部变量,那么只要把getN作为返回值,我们不就可以在getNum外部读取它的内部变量了吗

function getNum(){    var n = 100;    function getN(){ console.log(n);    }    return getN;}var result = getNum();result(); // 100

闭包的概念

上述代码中的getN函数就是闭包

各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我们参考老前辈的理解是:闭包就是能够读取其他函数内部变量的函数

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

     function getName(){     var username = "it";     function innerGetName(){  return username;     }     return innerGetName; } var result = getName(); var uname = result(); console.log(uname);//it    

JavaScript_闭包特点

  1. 读取函数内部的变量
  2. 变量的值始终保持在内存中

  读取函数内部的变量

function getNum(){    var n = 100;    function getN(){ console.log(n);    }    return getN;}var result = getNum();result(); // 100

变量的值始终保持在内存中

观察多次调用函数,n的变化

function getNum(){    var n = 100;    n++;    console.log(n);}getNum(); // 101getNum(); // 101

n放入到函数中进行增加,然后观察n的变化

function getNum() {    var n = 100;    nAdd = function () { //前面没有var 表示全局函数 n += 1     }    console.log(n);}getNum(); // 100nAdd();getNum() // 100

增加闭包,再观察n的变化

function getNum() {    var n = 100;    nAdd = function () {  n += 1     }    function getN() { console.log(n);    }    return getN;}var result = getNum();result(); // 100nAdd();result(); // 101

使用闭包的注意点

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题

function getNum() {    var n = 100;    function getN() { n += 1; console.log(n);    }    return getN;}var result = getNum();result();//101result();//102

JavaScript_闭包应用场景

 创建一个函数,声明一个数组,然后向数组中放入一个函数,函数值为i * i

function count() {    var arr = [];    for (var i = 1; i <= 3; i++) { arr.push(function () {     return i * i; });    }//循环结束i = 4 ,之前的i被覆盖    return arr;}var results = count();var f1 = results[0];var f2 = results[1];var f3 = results[2];console.log(f1(),f2(),f3()); // 16 16 16

原因就在于返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了4,因此最终结果为16

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变

function count() {    var arr = [];    for (var i = 1; i <= 3; i++) { arr.push((function (n) {     return function () {  return n * n;//利用闭包帮我们保存变量     } })(i));    }    return arr;}var results = count();var f1 = results[0];var f2 = results[1];var f3 = results[2];f1(); // 1f2(); // 4f3(); // 9

JavaScript_闭包中的this关键字