[关闭]
@GivenCui 2016-06-15T09:39:27.000000Z 字数 3634 阅读 925

第三课 闭包和JSON

js高级



目录



JS课程合集跳转链接


一. 闭包

闭包的相关概念

  • 概念 : 在函数式编程的语言中,闭包的应用广泛. 闭包就是函数内部嵌套另外一个函数(内部函数) , 内部函数引用了外部函数的局部变量,这样就能形成闭包.内部函数中包含了内部函数的代码以及外部函数的局部变量的引用.

  • 闭包的最大特点 : 外部函数执行完毕以后, 内部函数对其外部变量的引用, 不会被销毁, 继续存在于内存中. 一般闭包程序的外部函数都会有返回值, 这个返回值是其内部函数. (注意 : 返回值一般都是内部函数)

  • 支持闭包的语言具备的特性 :
    1. 函数可以作为参数进行传递
    2. 函数可以赋值给变量
    3. 函数可以作为返回值
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>闭包</title>
  6. <script type="text/javascript">
  7. /*
  8. * 思考一个问题 :
  9. * 1. 引用
  10. * 2. 形参
  11. * 3. 指针
  12. *
  13. */
  14. // 函数嵌套, 就是一个函数内部有另外一个函数
  15. // 立即调用的情况
  16. function fn1 () {
  17. var num = 100; // 通过闭包能把num在外部使用
  18. function subFn1 (num1) {
  19. console.log("num is " + (num + num1));
  20. console.log("我是一个嵌套函数的子函数 . ");
  21. }
  22. subFn1(50); // 嵌套函数的子函数的内部调用
  23. }
  24. fn1();
  25. // 可以把内部函数当做外部函数的返回值 , 实现不立即执行,在任何时候调用函数内部函数都OK
  26. // 内部函数中引用的外部函数的变量会一直存在
  27. function fn2 () {
  28. var num2 = 100;
  29. function subFn2 (param) {
  30. console.log("num2 is " + (num2 + param));
  31. }
  32. return subFn2; // 返回函数本身(代码块)
  33. }
  34. // alert(fn2()) ;
  35. // console.log(fn2()) ;
  36. var resultFn2 = fn2();
  37. resultFn2(500); // 在代码某处, 想调用时在调用
  38. // 自增操作 可以证明闭包可以让局部变量存在内存中,不被销毁
  39. function fn3() {
  40. var count = 0;
  41. /*
  42. // 第一种
  43. function subFn3 () {
  44. console.log("count is " + (++count));
  45. }
  46. return subFn3;*/
  47. // 不用引用,返回匿名函数
  48. return function() {
  49. console.log("count is " + (++count));
  50. }
  51. }
  52. var resultFn3 = fn3();
  53. resultFn3();
  54. resultFn3();
  55. resultFn3();
  56. console.log("***********************************************");
  57. // 每次运行完外部函数, 都会生成一个新的内部函数
  58. var resultFn4 = fn3(); // resultFn4 与 resultFn3是不同的引用,互不影响
  59. resultFn4();
  60. resultFn4();
  61. console.log(resultFn3 === resultFn4);
  62. // 需求 : 判断两个对象任一属性值的大小
  63. // 创建两个字面量对象
  64. var obj1 = {
  65. name : "a",
  66. age : 18
  67. }
  68. var obj2 = {
  69. name : "b",
  70. age : 15
  71. }
  72. // 访问对象的属性不仅有" . "语法, 还可以使用[] 来访问
  73. // []可以用来使用为形参的属性
  74. // 还可以用来使用有空格可属性等
  75. console.log(obj1["name"]); // ["name"]是属性name , 如果[name]表示name是个形参
  76. console.log(obj1.age > obj2.age); // 这只是实现了一次(完善: 封装)
  77. // 完善 : 封装
  78. // 比较两个对象任意属性值的大小
  79. // 外部函数的参数要比较的属性的名字
  80. // 用闭包实现特别的灵活
  81. function comparePropertyFn(propertyName) {
  82. // 返回内部函数,参数是两个要比较的对象
  83. return function (obj1, obj2) {
  84. // 通过属性名字获得值,用[]来用属性
  85. var value1 = obj1[propertyName];
  86. var value2 = obj2[propertyName];
  87. // 判断
  88. if(value1 > value2){
  89. return 1;
  90. }else if( value1 === value2){
  91. return 0;
  92. }else{
  93. return -1;
  94. }
  95. }
  96. }
  97. // 获得内部比较函数
  98. var resultCompareFn = comparePropertyFn("age");
  99. var resultValue = resultCompareFn(obj1, obj2);
  100. console.log(resultValue); // 1 即obj1.age > obj2.age
  101. var resultCompareFn2 = comparePropertyFn("name");
  102. var resultValue2 = resultCompareFn2(obj1, obj2);
  103. console.log(resultValue2); // -1 即obj1.name < obj2.name
  104. </script>
  105. </head>
  106. <body>
  107. </body>
  108. </html>

闭包注意事项

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

闭包思考题

代码一

  1. var name = "The Window";
  2.   var object = {
  3.     name : "My Object",
  4.     getNameFunc : function(){
  5.       return function(){
  6.         return this.name;
  7.       };
  8.     }
  9.   };
  10.   alert(object.getNameFunc()());

代码二

  1. var name = "The Window";
  2.   var object = {
  3.     name : "My Object",
  4.     getNameFunc : function(){
  5.       var that = this;
  6.       return function(){
  7.         return that.name;
  8.       };
  9.     }
  10.   };
  11.   alert(object.getNameFunc()());

二、JSON

JSON的概念

JSON : JavaScript Object Notation ,是一种轻量级数据交换格式.
XML也是一种数据交换格式.但是是重量级的.但是格式清晰


JSON并不是JS独有的,大部分语言都支持JSON格式,在我们JS中, 用来和服务器端做数据格式交换的.

JSON的结构

JSON是javascript的子集,它的结构由javascript对象和数组组成. 由这两种结构可以组合任何复杂的结构.

JSON的语法

1.并列的数据用" , " 表示
2.映射用" : " 表示
3.并列数据的数组用" [ ] "包裹
4.并列数据的对象用" { } "包裹

JSON的数值类型

1.number类型 : 和JS中的number一样
2.boolean类型 : 同JS
3.string类型 : 同JS
4.null类型 : 同JS
5.array类型 : 同JS
6.object类型 : 同JS

序列化和反序列化

序列化
把JS对象转换成JSON格式字符串, 通过网络给其它应用程序。
JSON.stringify()方法


反序列化
把JSON字符串转换成JS对象.
JSON.parse()方法


  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>JSON</title>
  6. <script type = "text/javascript">
  7. // 创建一个自变量对象
  8. var person = {
  9. name : "王晓晓",
  10. age : 27,
  11. dog : {
  12. dogName : "Nimo"
  13. },
  14. friends : [
  15. {
  16. friendName : "小李"
  17. },
  18. {
  19. friendName : "小刘"
  20. }
  21. ],
  22. isMarry : false
  23. }
  24. // 转换成JSON格式
  25. var jsonStr = JSON.stringify(person);
  26. console.log(jsonStr);
  27. // 再转回字面量对象
  28. // 反序列化
  29. var jsObj = JSON.parse(jsonStr);
  30. console.log(jsObj);
  31. </script>
  32. </head>
  33. <body>
  34. </body>
  35. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注