zoukankan      html  css  js  c++  java
  • web前端基础知识-(三)JavaScript基本操作

    JavaScript 是一种轻量级的编程语言。

    JavaScript 是可插入 HTML 页面的编程代码。

    JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。

    JavaScript 很容易学习。

    一、如何编写?

    1.JavaScript代码存在形式

    <!-- 方式一 -->
    <script type="text/javascript" src="JS文件"></script>
      
    <!-- 方式二 -->
    <script type="text/javascript">
        Js代码内容
    </script> 

    2.JavaScript存放位置 

    HTML 中的脚本必须位于 <script> 与 </script> 标签之间。 

    脚本可被放置在 HTML 页面的 <body> 和 <head> 部分中。

    由于Html代码是从上到下执行,如果Head中的js代码耗时严重,就会导致用户长时间无法看到页面,如果放置在body代码块底部,那么即使js代码耗时严重,也不会影响用户看到页面效果,只是js实现特效慢而已。

    这里,推荐放在body体底部;

    3.注释

    JavaScript 不会执行注释。

    我们可以添加注释来对 JavaScript 进行解释,或者提高代码的可读性。

    单行注释以 // 开头。

    // 输出标题:
    document.getElementById("myH1").innerHTML="欢迎来到我的主页";
    // 输出段落:
    document.getElementById("myP").innerHTML="这是我的第一个段落。";
    

    多行注释以 /* 开始,以 */ 结尾。

    /*
    下面的这些代码会输出
    一个标题和一个段落
    并将代表主页的开始
    */

    二、变量

    JavaScript中变量的声明是一个非常容易出错的点,局部变量必须一个 var 开头,如果未使用var,则默认表示声明的是全局变量。

    JavaScript 变量可用于存放值(比如 x=5)和表达式(比如 z=x+y)。

    var x=5;
    var y=6;
    var z=x+y;

    变量可以使用短名称(比如 x 和 y),也可以使用描述性更好的名称(比如 age, sum, totalvolume)。

    • 变量必须以字母开头
    • 变量也能以 $ 和 _ 符号开头(不过我们不推荐这么做)
    • 变量名称对大小写敏感(y 和 Y 是不同的变量)

    JavaScript 语句和 JavaScript 变量都对大小写敏感。

    <script type="text/javascript">
     
        // 全局变量
        name = 'seven';
     
        function func(){
            // 局部变量
            var age = 18;
     
            // 全局变量
            gender = "男"
        }
    </script>

    三、数据类型 

    JavaScript 中的数据类型分为原始类型和对象类型:

    • 原始类型
      • 数字
      • 字符串
      • 布尔值
    • 对象类型
      • 数组
      • 字典
      • ...

    1.数字

    JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示。

    转换:

    • parseInt(..)    将某值转换成数字,不成功则NaN
    • parseFloat(..) 将某值转换成浮点数,不成功则NaN

    特殊值:

    •  NaN,非数字。可使用 isNaN(num) 来判断。
    • Infinity,无穷大。可使用 isFinite(num) 来判断。

    2.字符串

    字符串是由字符组成的数组,但在JavaScript中字符串是不可变的:可以访问字符串任意位置的文本,但是JavaScript并未提供修改已知字符串内容的方法。

    常见功能:

    obj.length 获取当前字符串长度
    obj.trim() 移除空白
    obj.trimLeft()
    obj.trimRight)
    obj.charAt(n) 返回字符串中的第n个字符
    obj.concat(value, ...) 拼接
    obj.indexOf(substring,start) 子序列位置
    obj.lastIndexOf(substring,start) 子序列位置
    obj.substring(from, to) 根据索引获取子序列---起始位置,结束位置
    obj.slice(start, end) 切片
    obj.toLowerCase() 大写
    obj.toUpperCase() 小写
    obj.split(delimiter, limit) 分割
    obj.search(regexp) 从头开始匹配,返回匹配成功的第一个位置(g无效)
    obj.match(regexp) 全局搜索,如果正则中有g表示找到全部,否则只找到第一个。
    obj.replace(regexp, replacement) 替换,正则中有g则替换所有,否则只替换第一个匹配项,
    $数字:匹配的第n个组内容;
    $&:当前匹配的内容;
    $`:位于匹配子串左侧的文本;
    $':位于匹配子串右侧的文本
    $$:直接量$符号

    3.布尔类型

    布尔类型仅包含真假,与Python不同的是其首字母小写。

    • ==      比较值相等
    • !=       不等于
    • ===   比较值和类型相等
    • !==    不等于
    • ||        或
    • &&    且

    4.数组

    JavaScript中的数组类似于Python中的列表。

    常见功能:

    obj.length          数组的大小
    obj.push(ele)       尾部追加元素
    obj.pop()           尾部获取一个元素
    obj.unshift(ele)    头部插入元素
    obj.shift()         头部移除元素
    obj.splice(start, deleteCount, value, ...)  插入、删除或替换数组的元素
                        obj.splice(n,0,val) 指定位置插入元素
                        obj.splice(n,1,val) 指定位置替换元素
                        obj.splice(n,1)     指定位置删除元素
    obj.slice( )        切片
    obj.reverse( )      反转
    obj.join(sep)       将数组元素连接起来以构建一个字符串
    obj.concat(val,..)  连接数组
    obj.sort( )         对数组元素进行排序

    四、小知识汇总

    1. 序列化

    序列化就是将JavaScript中的数据类型转换成字符串,反序列化的过程则相反;

    var a="ss";
    ret = JSON.stringify(a);//序列化
    console.log(ret);
    
    console.log(JSON.parse(ret));//反序列化
    

    结果如下:

    2. 转义

    一般使用在URL中字符的转义等,下面来看一下具体的用法

    var a='http://www.baidu.com?name=民资';
    console.log(encodeURI(a));
    console.log(decodeURI(encodeURI(a)));
    console.log(encodeURIComponent(a));
    console.log(decodeURIComponent(encodeURIComponent(a)));
    

    结果如下:

    3. eval

    JavaScript中的eval是Python中eval和exec的合集,既可以编译代码也可以获取返回值。

    console.log(eval('1+2*5')); 
    console.log(eval(a = 1));    

    结果如下:

    4. 时间

    在JavaScript中,Date对象用来表示日期和时间。JavaScript中提供了时间相关的操作,分别为获取时间和设置时间,时间操作中分为两种时间,统一时间(UTC),以及本地时间(东8区)

    var now = new Date();
    now.getFullYear(); //2016
    now.getMonth(); // 月份,注意月份范围是0~11,6表示7月
    now.getDate(); // 日期
    now.getDay(); // 表示星期几
    now.getHours(); // 24小时制
    now.getMinutes(); // 分钟
    now.getTime(); // 以number形式表示的时间戳
    

    结果如下:

    五、循环和条件语句

    1. 条件语句

      if(条件){
      
        }else if(条件){
              
        }else{
      
        }
     
     
    switch(name){
            case '1':
                age = 123;
                break;
            case '2':
                age = 456;
                break;
            default :
                age = 777;
        }

    2.for循环和while循环

    for循环

    循环时,循环的元素是索引

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <script>
            var names = ["cc", "tony", "rain"];
            for(var i=0;i<names.length;i++){
                console.log(i);
                console.log(names[i]);
            }
        </script>
    </body>
    </html>

    执行结果:

    while循环,同python中的while循环

     while(条件){
            
            
            }

    五、函数

    1.函数类型

    JavaScript中函数基本上可以分为以下三类:普通函数,匿名函数,自执行函数。

    此外需要注意的是对于JavaScript中函数参数,实际参数的个数可能小于形式参数的个数,函数内的特殊值arguments中封装了所有实际参数。

    //函数
            function func(arg){
            
                return arg+1
            }
            var result = func(1)
            console.log(result);
    
    //普通函数:
        function func(){
            
        }
    //匿名函数:
        
        function func(arg){
        
            return arg+1
        }
        
        setInterval("func()", 5000);
        
        setInterval(function(){
            console.log(123);
        
        },5000)
        
    //自执行函数(创建函数并且自动执行):
        (function(arg){
            console.log(arg);
        })(1)        
    //自执行函数等同于以下代码:
        function func(arg){
            console.log(arg);
        }
        func(1)
        

    2.函数作用域

    作用域在许多程序设计语言中非常重要。

    通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

    作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。

    首先,了解下其他语言的作用域:

    • 其他语言以代码块为作用域
    public void Func(){
                            if(1==1){
                                string name = 'Java';
                                
                            }
                            console.writeline(name);
                            
                        }
                        Func()
                        // 报错
    
    • python以函数作为作用域
    情况一:
        def func():
            if 1==1:
                name = 'alex'
            print(name)
            
        func()
        // 成功
    情况二:
        def func():
            if 1==1:
                name = 'alex'
            print(name)
            
        func()
        print(name)
        // 报错
    

    而javascript的作用域具有如下特点:

    2.1 以函数作为作用域

    先看下以下代码:

    var name='cc';
    function func(){
        console.log(name);
        if(1==1){
            var name = 'dd';
        }
        console.log(name);
    }
    func()

    第一句输出的是:undefined,而不是cc;

    第二句输出的是:dd

    大家可能认为第一句会输出cc,因为代码还未执行var name='dd';所以肯定会输出cc;

    上面我们已经说过,javascript是以函数作为作用域。实际上以上代码可重新编写:

    var name='cc';
    function func(){
        var name;
        console.log(name);
        if(1==1){
            var name = 'dd';
        }
        console.log(name);
    }
    func()
    

    name声明覆盖了全局的name,但还没有赋值,所以输出undefined;

    2.2 函数的作用域在函数未被调用之前,已经创建

    function func(){
        if(1==1){
            var name = 'cc';
        }
        console.log(name);
    }

    2.3 函数的作用域存在作用域链,并且也是在被调用之前创建

    我们来看第一个例子:

    xo = "cc";
    function func(){
        var xo = 'eric';
        function inner(){
            var xo = 'tony';
            console.log(xo);
        }
        
        inner()
    }
    
    func()

    输出:tony;

    注释掉var xo='tony';一行,输出:eric;

    同时注释掉var xo='tony';和var xo='eric';输出cc;

    示例二:
        xo = "cc";
        
        function func(){
            var xo = 'eric';
            function inner(){
                
                console.log(xo);
            }
            
            return inner;
        }
        
        var ret = func()
        ret()
    
    示例三:
        xo = "alex";
        
        function func(){
            var xo = 'eric';
            function inner(){
                
                console.log(xo);
            }
            var xo = 'tony';
            
            return inner;
        }
        
        var ret = func()
        ret()

    2.4 函数内局部变量声明提前

    function func(){
        console.log(name);
    }
    
    func();
    // 程序直接报错
    
    function func(){
        console.log(name);
        var name = 'cc';
    }
    //解释过程中:var name;
    
    func();
    // undefined
    

    3. javascript高级知识-词法分析

    js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

    • 分析参数;

    • 再分析变量的声明;

    • 分析函数说明;

    具体步骤如下:

    • 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO;

    • 分析参数

    1. 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefined;

    2. 接收实参,添加到AO的属性,覆盖之前的undefined;

    • 分析变量声明,如var age;或var age=23;

    1. 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefined,即AO.age=undefined;

    2. 如果AO上面已经有age属性了,则不作任何修改;

    • 分析函数的声明,如果有function age(){};把函数赋给AO.age ,覆盖上一步分析的值;

    这样说可能大家不是很理解,下面结合具体的例子看下:

    3.1 例1:

    <script>
        function t1(age) {
            console.log(age);
            var age = 27;
            console.log(age);
            function age() {}
            console.log(age);
        }
        t1(3);
    </script>
    

    词法分析阶段:

    1)首先形成active object对象,即AO对象;

    2)第一步分析形参:

    AO.age=undefined;

    传入实参即对AO.age=undefined进行覆盖:AO.age=3;

    3)第二步分析局部变量:

    存在var age=27;

    这个时候遵循如果AO.age存在值则不作任何修改.按照第一步分析的最后结果AO.age = 3,所以这里不作任何修改即:AO.age = 3

    4)第三步:分析函数的声明:

    因为函数中存在function age(){}函数

    所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 3即:

    AO.age = function age(){}

    执行阶段:

    执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

    function age(){}

    var age=27;给age赋值27

    到第二个console.log(age)这个时候age已经重新被赋值27,所以这个时候会打印:

    27

    function age() 并没有调用所以并不会执行

    到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

    27 

    运行js查看结果如下与我们分析的完全相符:

    3.2 代码例子2:

    function t1(age) {
            var age;
            console.log(age);
            var age = 23;
            console.log(age);
            function age() {}
            console.log(age);
        }
    t1(22)
    

    词法分析阶段:

    • 首先形成Active Object即AO对象

    • 第一步:分析形式参数

    AO.age = undefine

    传入实参即对AO.age=undefine进行覆盖:

    AO.age = 22

    • 第二步:分析局部变量

    第一步中最后得到AO.age = 22

    所以这里var age;以及var age =23 ,因为AO.age属性已经存在值,所以这个时候遵循如果存在则不作任何修改,即:

    AO.age = 22

    • 第三步:分析函数的声明,

    因为函数中存在function age(){}函数

    所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

    AO.age = function age(){}

    执行阶段:

    执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:

    function age(){}

    var age=23;给age赋值23

    到第二个console.log(age)这个时候age已经重新被赋值23,所以这个时候会打印:

    23

    function age() 并没有调用所以并不会执行

    到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:

    23

    运行js查看结果如下与我们分析的完全相符:

    3.3 代码例子3

    function t1(age) {
        var age;
        console.log(age);
        age = 23;
        console.log(age);
        function age() {
            console.log(age);
        }
        age();
        console.log(age)
    }
    t1(22)
    

    词法分析阶段:

    • 首先形成Active Object即AO对象

    • 第一步:分析形式参数

    AO.age = undefine

    传入实参即对AO.age=undefine进行覆盖:

    AO.age = 22

    • 第二步:分析局部变量

    第一步中最后得到AO.age = 22,所以这里遵循,如果AO.age存在值则不作任何修改即:

    AO.age = 22

    • 第三步:分析函数的声明

    因为函数中存在function age(){console.log(age)}函数

    所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:

    AO.age = function age(){console.log(age)}

    执行阶段:

    执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:

    function age(){console.log(age)}

    age = 23,这个时候会覆盖原来的function age(){console.log(age)},所以第二个console.log(age)会打印:

    23

    function age() 是一个函数表达式,所以不会做任何操作

    age() 这个时候的age还是23,并不是函数表达式,所以这里会报错

    运行js查看结果如下与我们分析的完全相符:

    六、面向对象

    1. 创建对象

    function Foo(n){ //构造函数
        this.name = n;//this等同于python面向对象的self
        this.sayName = function(){
            console.log(this.name);
        }
    }
    var obj1 = new Foo('we'); //要创建对象的实例必须要用new操作符
    obj1.name
    obj1.sayName()
    var obj2 = new Foo('wee'); //obj1 obj2都是Foo对象的实例
    obj2.name
    obj2.sayName()

    构造函数的缺点:使用构造函数创建每个实例的时候,构造函数里的方法都要在每个实例上重新创建一遍,这样会浪费内存;

    2. 原型

    为了解决上述问题,javascript引入了一个prototype-原型;

    我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象;

    用途:包含可以由特定类型的所有实例共享的属性和方法;

    理解:prototype是通过调用构造函数创建的那个对象的原型对象;

    使用原型的好处是可以让所有对象实例共享它所包含的属性和方法;

    也就是说,不必在构造函数中定义对象信息(属性/方法),而是可以直接将这些信息添加到原型中;

    function Foo(n){
        this.name = n;
    }
    # Foo的原型
    Foo.prototype = {
        'sayName': function(){
            console.log(this.name)
        }
    }
    
    obj1 = new Foo('we');
    obj1.sayName()
    
    obj2 = new Foo('wee');
    

    具体可参照http://www.jb51.net/article/63876.htm

  • 相关阅读:
    Tomcat性能调优
    spring 提供的可扩展的接口和类
    Spring boot 定义exit codes 让你定位问题更加简单
    spring中@Async注解的原理和使用
    SpringCache源码深度解析
    ApplicationContextAware和BeanFactoryAware使用理解
    spring aop中引介拦截器的用法
    提高安全性而在HTTP响应头中可以使用的各种响应头字段
    spring aop中targetSource的理解
    PowerMockito使用PowerMockIgnore注解消除类加载器引入的ClassCastException
  • 原文地址:https://www.cnblogs.com/cocc/p/6068957.html
Copyright © 2011-2022 走看看