• javascript基础的一些总结


    一 闭包

    各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
    由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。
    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
        function f1(){
    var n=999;
    function f2(){
    alert(n);
    }
    return f2;
    }
    var result=f1();
    result(); // 999
    上一段代码中的f2函数,就是闭包。

    闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中:
    function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
    alert(n);
    }
    return f2;
    }
    var result=f1();
    result(); // 999
    nAdd();
    result(); // 1000

    二 JS中函数声明与函数表达式的不同  

    Js中的函数声明是指下面的形式:function functionName(){}
    这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如:var functionName = function(){} 
    看到这两一种写法时会产生疑惑,这两种写法差不多,在应用中貌似也都是可行的,那他们有什么差别呢?
    事实上,js的解析器对函数声明与函数表达式并不是一视同仁地对待的。对于函数声明,js解析器会优先读取,
    确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,
    只在执行到某一句时也会对其进行解析,所以在实际中,它们还是会有差异的,具体表现在,
    当使用函数声明的形式来定义函数时,可将调用方式在函数声明之后,而后者,这样做会报错。

    三 数值

    NaN“非数值”,具有毒性,bug。typeof类型是number(这是typeof操作符最奇怪的行为之一)。

    .1+.2 结果为0.30000000000000004。
    利用Math.round()方法获得两位数的精度。
    Math.round((.1+0.2)*100)/100 结果为0.3;

    "sdxf".indexOf("x")在sdxf中出现的位置:3
    "sdxf".charAt(4)在sdxf中的第4位字母是:f

    类型比较:1=="1"返回true,1==="1"返回false。

    变量:i=0,隐式声明,隐式声明的变量总是具有全局作用域的,即使该变量是在某个函数函数体中声明。(建议用var关键字声明,而且建议在作用域的顶部声明)
    var i=0;显式声明。
    var i;未初始化,包含特定的值undefined。

    四 对象

    对象:对象是属性的集合,每一个属性具有一个名称和一个值。属性可以包含除undefined外的任何类型,在创建对象之后可以对属性赋值。

    实例化对象,第一种方法使用new关键字:
    var myObject=new Object();
    new 关键字将调用构造函数,或者更通用的说法是构造器。构造器将初始化新创建的对象。
    构造函数:
    function cName(name){
        alert(name);
    }

    var ccname=new cName("构造函数");

    实例化对象,第二种方法使用字面量(这种方式创建对象更像其他语言中的散列【hash】或关联数组):
          var myObject={};
          var domArr={
                 "name":"构造函数2",
                 "age":myObject

             }
             var nm=domArr["name"];//可以用.,如下
             var ag=domArr.age;
             alert(nm);
             alert(ag);
            
    因为属性也可以是对象,可以在任意层上嵌套对象:
    var tem={ "name":{"bbo":{"uu":"h", "dd":"i"}}};
    alert(tem.name.bbo.uu) 结果为 h。

    javascript是一种动态语言,因此要更新一个属性,只需要重新对属性值赋值即可。要移除一个属性,只需使用delete操作符,删除不存在的属性不存在危险。

    javascript使用原型继承,对象直接从其他对象继承,从而创建新的对象。简而言之,对象继承另外一个对象中的属性。因为javascript中没有类。

    例如,人,javascript中是没有人这个类的,而是张三继承了李四这个人的特征【属性】(眼睛,鼻子,年龄等),形成了新的对象“张三”。

    在创建新对象时,注意对象的初始化:
    var object1=object2={}//引用的是同一个对象。
    var object1={},object2={}//引用的不是同一个对象。

    五 函数、闭包、变量

    我们认为尽量避免使用全局变量,但有些情况是必须的,所以我们会采取一些办法避免扰乱全局名称空间。
    一种办法是使用单个全局变量作为顶层对象,包含程序或框架中的所有方法和属性。安装惯例,命名空间都采用全部字母大写,但值得注意的是常量也用大写格式。
    BBNN_PPO={};
    BBNN_PPO.Clem={
        "name":"agele",
        "age":"5"
    }
    BBNN_PPO.Dem={
        "name":"Cdiny",
        "age":"4.5"
    }

    另外一种是采用闭包:

    函数:函数是一个代码块,他封装了一系列的javascript语句。函数可以接收参数,也可以返回值。
    与c#和java不同,javascript中的函数是第一类(first-class)的对象。

    返回值,接参数:
    function calc(x){
        return x*10;
    }
    alert(calc(30));
    结果300。


    如果函数没有返回一个特定的值,则它将返回一个undefined的值:
    var x=2;
    function calc()
    {
        x=x*10;
    }
    alert(x);//结果为20
    alert(calc());//结果为 undefined

    函数赋值给一个变量:
    var calc=function(x)
    {
        return x*2;
    }
    alert(calc(5));//结果为 10。
    给函数名使用圆括号,将执行该函数并返回函数的值,而不是返回对该函数的引用。

    将函数作为参数传递给其他函数:
    function demo(fn){
        alert("这是接收来的:"+fn());
        }
        demo(function(){ return "大哥哥"});
        //结果为“这是接收来的:大哥哥”

    二式:
    function demo(fn)
    {
        alert("这是接收来的:"+fn());
    }
    function calc()
    {
        return 2*3;
    }
    demo(calc);
    //结果为“这是接收来的:6”

    匿名函数:一个特别重要的变体就是立即调用函数表达式,或称为自执行匿名函数。
    这一模式的本质是将一个函数表达式包装在一对括号中,然后立即调用该函数。
    这一技巧非常简单,将函数表达式包装在一对圆括号中,将迫使javascript引擎将function(){}块识别为一个函数表达式,而不是一个函数语句的开始。

    (function(x,y){
        alert(x+y);
        })(5,6);//结果为 11,最后这圆括号(5,6),可以写在前面个圆括号内

    由于这一的函数表达式将被立即调用,因此该模式用于确保代码块的“执行上下文”按照预的期效果执行,这是这种模式最重要的用途之一。
    通过将参数传入函数,在执行时就可以捕获函数所创建的闭包中的变量。
    闭包就是这样一个函数:它处在一个函数体中,并应用了函数体当前“执行上下文”中的变量。

    闭包的应用,及函数中将另外一个函数作为返回值:

        var x=24;
        alert(x);结果为:24
        var message=(function(x){
            return function(){//函数中另外一个函数作为返回值
                alert("闭包中的x是:"+x);//结果是:闭包中的x是:24
            }
        })(x);
        message();//没结果
        x=12;
        alert(x);//结果为:12
        message();//结果是:"闭包中的x是:24",无论外部作用域x的值发生什么变化,闭包将记住函数执行时变量x的值。

    “执行上下文”:它是一种对象,代码在“执行上下文”环境中执行。可以通过this关键字来访问“执行上下文”,this关键字是对当前“执行上下文”对象的引用。
    若代码不存在于用户自定义对象或函数中,那么它将属于“全局上下文”。
    在javascript中,没有定义具体“上下文”的函数,将把它们的this关键词的值绑定为undefined值。
    alert(this);//[object DOMWindow]

    eval函数setTimeout函数具有自己独立的“执行上下文”。

    在开始执行一个函数或方法时,javascript创建了一个新的“执行上下文”并进入该函数的“执行上下文”,当函数执行完毕并返回时,控制权将交给原来的“执行上下文”。
    在创建闭包时当前“上下文”将保留下来,否则当前“上下文”将被当着垃圾收集。

    作用域和闭包:
    讨论作用域时,考虑定义变量的位置和变量的生存期非常重要。作用域是指在什么地方可以使用该变量。
    在javascript中,作用域维持在函数级别,而不是块级别。因此,参数以及使用var关键字定义的变量,仅在当前函数中可见。

    嵌套函数:除了不能访问this关键字和参数之外,嵌套函数可以访问外部函数中定义的变量。这一机制是通过闭包来实现的,它指的是:即使在外部函数解释执行之后,内部嵌套函数继续保持它对外部函数的引用。闭包还有助于简绍名称空间的冲突。
    每次调用一个包裹(enclosed)的函数时,虽然函数的代码并每月改变,但是javascript将为每一次调用创建一个新的作用域。
    function getCom(value){
               return function(value){
                return value;
               }
            }
            var a=getCom(),b=getCom(),c=getCom();
            alert(a(0));//结果为 0 ,每一次调用都创建新的作用域
            alert(b(1));//结果为 1
            alert(c(2));//结果为 2
            alert(a===b);//false;
            });

    当定义一个独立函数(没有绑定任何对象)时,this关键字绑定与全局名称空间。
    作为一个最直接的结果,当在一个方法内创建一个函数时,内部函数的关键字this将绑定与全局名称空间,而不是绑定该方法。
    为了解决这个问题,可以将包裹方法的this关键字简单地赋值给一个名为that的中间变量。
    var     obj={};
            obj.mathod=function(){
                var that=this;
                this.counter=0;
                var count=function(){
                    that.counter+=1;
                    alert(that.counter);//上层函数定义的值传不进来
                }
                count();//结果为 1;
                count();//结果为 2;
                alert(this.counter);//当没有调用到内部函数时,值为0;现在值为2
            }
            obj.mathod();
    (个人理解:一个小偷,一个叫花子,都想吃到食物(内心世界=内部函数),小偷进入主人家(家=外部函数),但却找不到食物(食物=外部函数变量),叫花子侧在家门口(外部函数之外)乞讨,却得到了食物(函数变量),所以小偷想获得食物必须迂回到外部方能求得食物)

    在javascript中并没有官方的访问级别语法,javascript没有类似于java语言中的private或protected这样的访问级别关键字。默认情况下,对象中的成员都是共有和可访问的。但在javascript中可以实现与私有或公有属性类似的访问级别效果。要实现私有方法或属性,请使用闭包:
    function reTun(){
                var chaer="狠狠不如意";//私有

                this.oo=function(){//闭包
                    return chaer;//公有
                }
            }
            var dem=new reTun();
            alert(dem.chaer);//undefined
            alert(dem.oo());//狠狠不如意

            this.oo()是函数reTun的专有方法,它可以访问reTun中的私有成员。另外chaer变量是“私有”的,他的值只能通过专有方法进行访问


    使用模块:与私有和专有访问级别类似,在javascript中没有内置的包语法。模块模式是一种常用的编码模式

    TTMMOON={};// 创建名称空间
    TTMMOON.teme=(function(){//函数表达式
        var destion="",molde="",fulle="";//私有成员
        //公有访问方法
        return{
            //设置器
            setDestion:function(dest){
                this.destion=dest;
            },
            setModl:function(mold){
                this.molde=mold;
            },
            setFulle:function(full){
                this.fulle=full;
            },
            //访问器
            getDestion:function(){
               return this.destion;
            },
            getModl:function(){
               return this.molde;
            },
            getFulle:function(){
               return this.fulle;
            },
            //其他成员
            toString:function(){
                alert(this.getModl()+"-嗨,中国"+this.getFulle()+"-谢谢您们!"+this.getDestion());
            }
            //在这里执行初始化过程
        }
    }());
    var myTimeus=TTMMOON.teme;
    myTimeus.setModl("我叫joy,");
    myTimeus.setFulle(",我很开心");
    myTimeus.setDestion("我会回来的。");
    myTimeus.toString();

    });

    六、数据类型、javascript实践

    扩展类型:
    javascript支持将方法和其他属性绑定到内置类型,比如字符串、数值和数组类型。与其他任何对象类似,String对象也具有prototype属性。开发人员可以为String对象扩充一些便利的方法。例如,String没有将字符串false或true转换为布尔值的方法。
    可以用下面的代码为String对象添加该功能:
    String.ptrototype.boolean=function()
            {
                return "true"==this;
            };
            var t='true'.boolean();
            var f='false'.boolean();
            alert(t);//ture
            alert(f);//false

    简化二:
    Function.prototype.mathod=function(name,func)
    {
        this.prototype[name]=func;
        return false;
    }
    String.mathod("boolean",function(){
        return "true"==this;
    })
    "true".boolean();//true

    javascript的最佳实践:

    1、使用parseInt()函数将字符串转换为整数,但确保总是指定基数。更好的办法是使用一元操作符(+)将字符串转化为数值:
    Good:parseInt("010",10);//转化为十进制
    Better:+"010";//高效

    2、是用等同(===)操作符来比较两个值,避免意料之外的类型转换。
    类型比较:1=="1"返回true,1==="1"返回false。

    3、在定义对象字面量时,在最后一个值的结尾不要使用逗号:
    var obj={
                name : "any",
                age : "20"
            }

    4、不要使用with语句。
    5、在循环中创建函数应该谨慎小心,这种方式非常低效。
    6、eval()函数可以接受一个字符串,并将其视为javascript代码执行。应该限制eval()函数的使用,它很容易在代码中引入各种各样严重的安全问题。
    7、使用分号作为语句的结尾,当精简代码时特别有用。
    8、应该避免使用全局变量。应该总是使用var关键字来声明变量。将代码包裹在匿名函数中,避免命名冲突,请使用模块来组织代码。
    9、对函数名使用首字母大写表示该函数将作为new操作符的构造函数,但请不要对其他任何函数的函数名使用首字母大写。

  • 相关阅读:
    http请求工具类
    java订单号生成
    SpringUtil获取Spring容器对象
    git push的日志展示问题
    nodejs环境搭建,淘宝镜像cnpm
    csdn里面代码块颜色
    nginx简单使用
    vue项目打包后字体文件路径出错的解决办法
    VUE 爬坑之旅 -- 用 ES6 语法写一个工具类,并全局引用
    VUE 爬坑之旅 -- 用 ES6 语法写一个工具类,并全局引用
  • 原文地址:https://www.cnblogs.com/boyzi/p/3988228.html
Copyright © 2020-2023  润新知