以下更得是JavaScript函數以及闭包等内容,有需要的可参考前两篇博客,这里主要记得是HTML和css部分,这里主要记的是js最基础部分。
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 如果 a 大于 b,则上面的代码将退出函数,并不会计算 a 和 b 的总和 作用域是可访问变量的集合。 变量在函数内声明,变量为局部作用域,只能在函数内部访问。 变量在函数外定义,即为全局变量。全局变量有 全局作用域: 网页中所有脚本和函数均可使用。 js运行时会进行三件事:1语法分析 2.预编译 3.解释执行 语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误 预编译发生在函数执行的前一刻 imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象(window)所有,所有数据变量都属于 window 对象 此时a会被认为是全局的一个对象,即window所属的值 window就是全局 相当于 也就是 对预编译的浅显理解: 输出的结果为: a 输出结果为:undefined; 预编译的四部曲: 重要性是4>3>2>1 1.创建AO对象,我们隐式的在函数中创建了一个AO的对象来盛放函数中的变量,此时对象中并没有值; 2:找形参和变量声明,将变量和形参名作为AO()属性名,值为undefined 3.将实参值和形参值统一,此时将实参带入函数中,fn(1),因此AO中a 为 1 4.在函数体里找函数声明,值赋予函数体,由于在函数中有 function a() {} ,这一函数因此此时AO中 a = function a() {} 预编译完后进行执行: 结果为: 全局预编译: 结果为: undefined 执行过程: 原理: 只有表达式才能被执行 函数会将函数变成表达式 我们在调用test的时候可直接使用 这就是函数表达式,能被立即执行符号执行的表达式,再被立即执行之后,就变成了立即执行函数,执行完就销毁 添个加号或者-号就成表达式了: 括号也算数学表达式 函数声明加上一对括号变成函数表达式 加上一对括号让他执行。 先执行外面的括号,变成表达式,然后再执行里面的表达式 形式如下:由下图可见执行完之后函数已经被销毁了 下面是几个理解: 闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 Javascript允许使用内部函数—即函数定义和函数表达式位于另一个函数的函数体内。 只要将内部函数传递到所在的词法作用域以外,它都会持有对原始作用域的引用,无论在何处执行这个函数都会使用闭包。 输出 那我们怎么输出0-9呢 找了几个小练习再理解一下 这段代码本来像实现的功能是点击li标签输出的值为点击li的顺序值,但是结果是每次输出都是3… 我们同样用闭包解决这个问题 在for循环执行时,立即将当前的i值作为形参传入clickLi中,而形参默认为函数内的局部变量,函数外部是不能对i进行操作的。所以,当点击li时,执行clickLi函数时,打印出来的则是li的顺序值。 可以重复使用变量,并且不会造成变量污染 全局变量可以重复使用,但是容易造成变量污染。局部变量仅在局部作用域内有效,不可以重复使用,不会造成变量污染。闭包结合了全局变量和局部变量的优点。 可以用来定义私有属性和私有方法。 首先,需要了解浏览器自身的内存回收机制。 因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存,可能会引起内存泄漏 造成内存泄露的原因: 意外的全局变量(在函数内部没有使用var进行声明的变量) console.log 闭包 对象的循环引用 未清除的计时器 DOM泄露(获取到DOM节点之后,将DOM节点删除,但是没有手动释放变量,拿对应的DOM节点在变量中还可以访问到,就会造成泄露) 😃 再看一道题 问输出什么? 逗号运算符,它将第一个的参数,再计算第二个的参数值。然后返回最第二个参数的值
函数
function functionname() { // 执行代码 }
带参数的函数
-·变量和参数必须以一致的顺序出现。第一个变量就是第一个被传递的参数的给定的值。
<button onclick="myFunction('Harry Potter','Wizard')">点击这里</button> <script> function myFunction(name,job){ alert("Welcome " + name + ", the " + job); } </script>
return
function functionName(target){ //隐式调用 +自动转成number型 return +target; } var num=functionName('123'); console.log(typeof(num)+" "+num);
仅仅希望退出函数时function myFunction(a,b) { if (a>b) { return; } x=a+b }
插入几个小练习:
function scream(animal){ switch(animal){ case "dog": document.write('wang'); return; case "cat": document.write("miao"); return; } }
function add() { var sum = 0; for (var i = 0; i < add.arguments.length; i++) { sum += add.arguments[i]; } return sum; } alert(add(143,51,21,97));
arguments.length为函数实参个数
这里了解一下arguments的用法
function sum(){ var num = window.prompt("请输入你的值:"); var str = ""; for (var i = num.length-1;i >= 0; i--) { str +=transfer(num[i]); } document.write(str); } function transfer(target){ switch(target){ case "1": return "壹"; case "2": return "贰"; case "3": return "弎"; case "4": return "四"; case "5": return "伍"; case "6": return "陆"; case "7": return "七"; case "8": return "八"; case "9": return "玖"; } } sum();
function n(x) { if(x == 1) { return 1; } else { return x * n(x - 1); } } alert(n(5));
作用域
局部变量
局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。// 此处不能调用 carName 变量 function myFunction() { var carName = "Volvo"; // 函数内可调用 carName 变量 }
全局变量
var carName = " Volvo"; // 此处可调用 carName 变量 function myFunction() { // 函数内可调用 carName 变量 }
如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。
// 此处可调用 carName 变量 function myFunction() { carName = "Volvo"; // 此处可调用 carName 变量 }
变量生命周期
HTML 中的全局变量
预编译
小知识穿插:
我们先不定义直接赋值a=123;
相当于`window.b =123;`
我们这里声明一个变量a并赋值var a=123;
windows.a=123;
a=123;
<script> test(); functiont test(){ console.log('a'); } </script>
不是赋值,只是声明
。 <script> console.log(a); var a = 123; </script>
function a(){};, var b =function (){};//不会提升
1.创建AO对象,Activation Object,函数执行生成了存储空间库 2.找形参和变量声明,将变量和形参名作为AO对象属性名,值为undefined 3.将实参值和形参统一 4.在函数体里面找函数声明,值赋予函数体
举个例,形参变量实参一样情况下function fn (a) { console.log(a); var a = 123; console.log(a); function a(){}; console.log(a); var b =function (){}; console.log(b); } fn(1);
AO{ }
AO{ a:undefined b:undefined }
AO{ a:1 b:undefined }
AO{ a:function a(){} b:undefined d:function d(){} }
function a(){} 123 123 function (){}
生成GO对象 global object GO==window<script> global = 100; function fn(){ console.log(global); global=200; console.log(global); var global=300; } fn(); var global; </script>
200
global:undefined
js是块编译,即一个script块中预编译然后执行,再按顺序预编译下一个script块再执行
此时上一个script块中的数据都是可用的了,而下一个块中的函数和变量则是不可用的。立即执行函数
没有函数声明,在执行一次过后即被释放,除了这点与其他函数没有区别,适合做初始化工作。
立即执行函数也有预编译过程;
立即执行函数写法:(function (){ }()) //推荐
(function (){ })()
function test (){ var a=1; }
加个括号function test (){ var a=1; }()
这是函数声明,因为只有表达式才能够被(括号)执行
而上面的式子是函数声明,不是表达式。var test = function(){ console.log(123"); }()
+ function test (){ document.write("abc"); }()
- , !,&&(要能运行到函数) ,|| ,“+”
加上这些符号就变成了立即执行函数
所以:(function functionname (){ })
(function functionName (){ })()
把括号放在里面。(function functionName (){ console.log('a'); }())
根据立即执行函数的定义,发现functionName在使用后已经没有意义了;
接着我们去掉函数名,就是立即执行函数了 (function functionName(){ var a=1; var b=2; document.write(a+b); }())
与其他函数一样,可以传递实参和形参(function functionName(a,b){ document.write(a+b); }(1,2))
var num =(function test(a,b){ var c; c=a+b; return c; }(1,2))
闭包
闭包是将函数内部和函数外部连接起来的桥梁
这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。
当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。// JavaScript Document function test(){ var arr = []; for(var i = 0 ; i<10;i++) { arr[i] = function(){ document.write(i); } } return arr; } var myArr = test(); for(var j = 0 ; j<10;j++) { myArr[j]();//结果为10个10 }
记一下要注意的几点
函数体不是立刻执行,函数引用不打印函数体内语句也就是说 arr[i] = function(){
document.write(i); 执行位置不是他现在定义的位置,而是在函数调用的地方 myArrj;
当函数调用完成才会执行输出i
在函数外部可调用内部函数 return 函数与test()形成了闭包 都能用test()ao执行上下文arr随着for循环变化,for循环会产生十组数据,也就是内部函数执行10次。
十次结束后returnarr,将十组数据保存在外部,在外部执行,所以10个方法的i是共用的,在执行完test()后,此时的i相当于缓存在myArr中,且存入的值是test()的AO销毁前值,在销毁之前i存储的值是10
利用闭包解决闭包function test(){ var arr = []; for(var i = 0 ; i<10;i++) { (function(j){//此处隐式使用闭包的存储功能,存储的内容为j的数据 arr[j] = function(){ document.write(j); } }(i));//使用立即执行函数的实参,当执行myArr[i]时,查询的变量i即就转化为对应的立即执行函数的形参k } return arr; } var myArr = test(); for(var j = 0 ; j<10;j++) { myArr[j](); }
这里我们引入立即执行函数,循环十次的同时每个函数保存在arr里面的j都不同。
立即执行函数读到马上就会执行,读后销毁是相对于引用销毁,值依然被保留。闭包将内部函数作为返回值输出,然后用一个变量去接收外部函数的调用结果,即外部函数的返回值,通过调用这个变量就可以调用该函数了,如果是返回多个函数,则将其存于数组中,根据数组下标找到对应的函数。
<ul> <li>1</li> <li>2</li> <li>3</li> </ul>
function test(){ var lis = document.getElementsByTagName("li"); for (var i = 0; i < lis.length; i++) { (function(j){ lis[i].onclick = function() { console.log(i); } }(i)) } } test();
其实这个跟上段代码有相同之处,我们知识给li标签定义了点击属性,但是函数体不会立刻执行。
只有点击li时,函数执行,函数中的变量i没有在函数中定义,根据js的作用域链原则,会继续向上级作用域查询,因此找到了全局作用域中的i,这时for循环已经执行结束,此时全局作用域中的i已经变为了3,故打印出来的当然是3var lis = document.getElementsByTagName("li"); for (var i = 0; i < lis.length; i++) { lis[i].onclick = (function(i) { var clickLi = function() { console.log(i); } return clickLi; })(i) }
闭包的用途
使用闭包的注意点
什么是内存泄露
每个浏览器会有自己的一套回收机制,当分配出去的内存不使用的时候便会回收;内存泄露的根本原因就是你的代码中分配了一些‘顽固的’内存,浏览器无法进行回收,如果这些’顽固的’内存还在一直不停地分配就会导致后面所用内存不足,造成泄露。闭包造成内存泄漏
内存泄漏的解决方案
闭包的使用场景
var f=( function f(){ return "1"; }, function g(){ return 2; } )(); console.log(typeof(f));
在看一个var x=1; if (function f() {} )){ x+=typeof f; } console.log(x);
输出 1undefined
if条件里面能执行,括号里面函数就成为表达式,不是函数定义 f就没得了
任何一个变量未经定义放在typeof不报错 返回字符串类型undefined
要不是字符串类型加起来就是非数 NaN
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算