@GivenCui
        
        2016-06-15T01:39:27.000000Z
        字数 3634
        阅读 1080
    js高级
- 概念 : 在函数式编程的语言中,闭包的应用广泛. 闭包就是函数内部嵌套另外一个函数(内部函数) , 内部函数引用了外部函数的局部变量,这样就能形成闭包.内部函数中包含了内部函数的代码以及外部函数的局部变量的引用.
 
- 闭包的最大特点 : 外部函数执行完毕以后, 内部函数对其外部变量的引用, 不会被销毁, 继续存在于内存中. 一般闭包程序的外部函数都会有返回值, 这个返回值是其内部函数. (注意 : 返回值一般都是内部函数)
 
- 支持闭包的语言具备的特性 :
 
- 函数可以作为参数进行传递
 - 函数可以赋值给变量
 - 函数可以作为返回值
 
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>闭包</title><script type="text/javascript">/** 思考一个问题 :* 1. 引用* 2. 形参* 3. 指针**/// 函数嵌套, 就是一个函数内部有另外一个函数// 立即调用的情况function fn1 () {var num = 100; // 通过闭包能把num在外部使用function subFn1 (num1) {console.log("num is " + (num + num1));console.log("我是一个嵌套函数的子函数 . ");}subFn1(50); // 嵌套函数的子函数的内部调用}fn1();// 可以把内部函数当做外部函数的返回值 , 实现不立即执行,在任何时候调用函数内部函数都OK// 内部函数中引用的外部函数的变量会一直存在function fn2 () {var num2 = 100;function subFn2 (param) {console.log("num2 is " + (num2 + param));}return subFn2; // 返回函数本身(代码块)}// alert(fn2()) ;// console.log(fn2()) ;var resultFn2 = fn2();resultFn2(500); // 在代码某处, 想调用时在调用// 自增操作 可以证明闭包可以让局部变量存在内存中,不被销毁function fn3() {var count = 0;/*// 第一种function subFn3 () {console.log("count is " + (++count));}return subFn3;*/// 不用引用,返回匿名函数return function() {console.log("count is " + (++count));}}var resultFn3 = fn3();resultFn3();resultFn3();resultFn3();console.log("***********************************************");// 每次运行完外部函数, 都会生成一个新的内部函数var resultFn4 = fn3(); // resultFn4 与 resultFn3是不同的引用,互不影响resultFn4();resultFn4();console.log(resultFn3 === resultFn4);// 需求 : 判断两个对象任一属性值的大小// 创建两个字面量对象var obj1 = {name : "a",age : 18}var obj2 = {name : "b",age : 15}// 访问对象的属性不仅有" . "语法, 还可以使用[] 来访问// []可以用来使用为形参的属性// 还可以用来使用有空格可属性等console.log(obj1["name"]); // ["name"]是属性name , 如果[name]表示name是个形参console.log(obj1.age > obj2.age); // 这只是实现了一次(完善: 封装)// 完善 : 封装// 比较两个对象任意属性值的大小// 外部函数的参数要比较的属性的名字// 用闭包实现特别的灵活function comparePropertyFn(propertyName) {// 返回内部函数,参数是两个要比较的对象return function (obj1, obj2) {// 通过属性名字获得值,用[]来用属性var value1 = obj1[propertyName];var value2 = obj2[propertyName];// 判断if(value1 > value2){return 1;}else if( value1 === value2){return 0;}else{return -1;}}}// 获得内部比较函数var resultCompareFn = comparePropertyFn("age");var resultValue = resultCompareFn(obj1, obj2);console.log(resultValue); // 1 即obj1.age > obj2.agevar resultCompareFn2 = comparePropertyFn("name");var resultValue2 = resultCompareFn2(obj1, obj2);console.log(resultValue2); // -1 即obj1.name < obj2.name</script></head><body></body></html>
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
代码一
var name = "The Window";var object = {name : "My Object",getNameFunc : function(){return function(){return this.name;};}};alert(object.getNameFunc()());
代码二
var name = "The Window";var object = {name : "My Object",getNameFunc : function(){var that = this;return function(){return that.name;};}};alert(object.getNameFunc()());
JSON : JavaScript Object Notation ,是一种轻量级数据交换格式.
XML也是一种数据交换格式.但是是重量级的.但是格式清晰
JSON并不是JS独有的,大部分语言都支持JSON格式,在我们JS中, 用来和服务器端做数据格式交换的.
JSON是javascript的子集,它的结构由javascript对象和数组组成. 由这两种结构可以组合任何复杂的结构.
1.并列的数据用" , " 表示
2.映射用" : " 表示
3.并列数据的数组用" [ ] "包裹
4.并列数据的对象用" { } "包裹
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()方法
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>JSON</title><script type = "text/javascript">// 创建一个自变量对象var person = {name : "王晓晓",age : 27,dog : {dogName : "Nimo"},friends : [{friendName : "小李"},{friendName : "小刘"}],isMarry : false}// 转换成JSON格式var jsonStr = JSON.stringify(person);console.log(jsonStr);// 再转回字面量对象// 反序列化var jsObj = JSON.parse(jsonStr);console.log(jsObj);</script></head><body></body></html>