• JavaScript学习(1):基础


      这篇文章里,我们来聊一些JavaScript的基础知识。

      1. 如何运行JavaScript?

      JavaScript是一种解释型的语言,它不需要提前编译。通常情况下,JavaScript会放在网页中,在浏览器中运行。我们也可以找到一些在线的可以运行JavaScript的平台,当然我们也可以在Firefox或者Chrome里运行。

      我在网上找到了一个可以在线运行的网站:runjs,文章中的代码都是在该网站上运行的。

      实际上,我们可以在本地创建一个简单的网页,然后通过编辑网页的方式来测试JavaScript代码。

      下面是代码的基本运行结构:

     1 $(document).ready(
     2     function(){
     3         //在这里调用外面的函数
     4         print(add(1,1));
     5     });
     6 
     7 //封装document.write
     8 function print(obj){
     9     document.write(obj);
    10     document.write("<br>");
    11 }
    12 
    13 //简单的示例方法
    14 function add(left, right){
    15     return left + right;
    16 }

      2. JavaScript基本数据类型

      JavaScript的基本数据类型包括6种:number/string/boolean/object/function/undefined。

      2.1 number类型

      number类型用来存储数值,它描述的是64位的浮点型数值。但Javascript并不能表示0-2e64之间的所有数值,因为它还需要表示非整数,包括复数、分数等。对于64位来说,需要使用11位来存储数字的小数部分,使用1位来表示正负,所以JavaScript实际上可以表示-2e52到2e52之间的值。

      2.2 string类型

      string类型用来表示文本,可以使用单引号或者双引号来包括文本,任何放在引号内的符号,都会被认为是string,但对于特殊符号,可能需要转义处理。

      2.3 boolean类型

      boolean类型只包括两个值:true和false。我们可以在程序中使用各种boolean表达式来得到true或者false,从而实现不同的业务分支处理。

      我们可以在表达式中包含多个条件,条件之间可以是与或非的关系,在计算时,优先级如下:||的优先级最低,其次是&&,然后是比较运算符,最后是其他运算符(例如!)。

      和其他许多语言一样,对于&&来说,当前面的条件为false时,后面的条件不再计算,对于||来说,当前面的条件为true时,后面的条件不再计算。

      来看下面的例子:

     1 function conditionTest(){
     2     var a = 1;
     3     var b = 1;
     4     var c = {"key":"old"};
     5     print(c["key"]);
     6     if (a==1) print("a = 1");
     7     if (a==1 && b==1) print("a == 1 && b == 1");
     8     if (a==1 || changeValue(c)) print(c["key"]);
     9     if (a==1 && changeValue(c)) print(c["key"]);
    10 }
    11 
    12 function changeValue(obj){
    13     obj["key"] = "changed";
    14     return true;
    15 }

      它的输出结果如下:

    old
    a = 1
    a == 1 && b == 1
    old
    changed

      可以看出,在使用||时,没有调用changeValue方法。

      2.4 undefined类型

      当我们声明了一个变量,但是没有对其赋值时,它就是undefined的,就像下面这样

    1 var b;
    2 print(b);

      在Javascript中,还有一个和undefined类似的值:null。undefined表示“变量已声明但是没有复制”,null表示“变量已赋值但为空”,需要注意的是undefined==null的值为true。

      2.5 类型转换

      我们在上面提到了undefined == null的值是true,但我们使用typeof操作时可以发现,null是object类型,这说明在比较的过程中,发生了类型转换。

      类型转换是指将一种类型的值转换成另外一种类型的值。我们使用==进行比较时,会有类型转换,我们可以使用===来禁止类型转换。

      来看下面的例子:

     1 function convertTypeTest(){
     2     var a = 1;
     3     var b = "1";
     4     print ("a:" + a);
     5     print ("b:" + b);
     6     print ("type of a:" + typeof a);
     7     print ("type of b:" + typeof b);
     8     print ("a==b:" + (a == b));
     9     print ("a===b:" + (a === b));
    10     print ("a===Number(b):" + (a === Number(b)));
    11     print ("String(a)===b:" + (String(a) === b));
    12     print ("type of undefined:" + typeof undefined);
    13     print ("type of null:" + typeof null);
    14     print ("undefined==null:" + (undefined == null));
    15     print ("undefined===null:" + (undefined === null));
    16 }

      输出结果如下:

    a:1
    b:1
    type of a:number
    type of b:string
    a==b:true
    a===b:false
    a===Number(b):true
    String(a)===b:true
    type of undefined:undefined
    type of null:object
    undefined==null:true
    undefined===null:false

      可以很明显看到==和===的区别。

      3. JavaScript基本逻辑流程控制

      和大部分编程语言一样,JavaScript的逻辑控制基本上也是分为顺序、循环和条件。

      3.1 顺序

      上面给出的各个示例代码都是顺序执行的。

      3.2 循环

      JavaScript使用for、while来完成循环,下面是一个从1加到100的例子:

    1 function loopTest(){
    2     var start = 1;
    3     var end = 100;
    4     var result = 0;
    5     for (i = start; i <= end; i++){
    6         result = result + i;
    7     }
    8     print (result);
    9 }

      3.3 条件

      JavaScript使用if、switch来完成条件判断,下面是一个关于分数分类的例子:

    1 function gradeLevel(grade){
    2     var level;
    3     if (grade <= 100 && grade >= 90) level="优秀";
    4     else if (grade >= 80) level = "良好";
    5     else if (grade >= 60) level = "及格";
    6     else level="不及格";
    7     print(level);
    8 }

      4. 函数

      函数是JavaScript很重要的一部分,它是模块化的基础。我们在上面的示例中已经定义了很多函数,接下来我们看一些更有意思的东西。

      4.1 变量的作用域

      在JavaScript中,变量的作用域可以分为全局作用域和局部作用域。在函数体内部声明的变量属于局部变量。

      来看下面的例子:

     1 var a = 1;
     2 
     3 function change1(){
     4     a=2;
     5 }
     6 
     7 function change2(){
     8     var a =3;
     9 }
    10 
    11 function print(obj){
    12     document.write(obj);
    13     document.write("<br>");
    14 }
    15 
    16 
    17 //调用顺序
    18     print(a);
    19     change1();
    20     print(a);
    21     change2();
    22     print(a);

      从运行结果可以看出,change1修改了全局变量a的值,但change2没有修改,这是因为在change2中定义了一个同名的局部变量,所以在该方法体内发生的操作只作用在局部变量上。

      4.2 嵌套函数

      JavaScript允许在函数体内嵌套函数,这样从某种程度上,可以控制一些变量在某些函数内共享。

      下面是一个实现四则运算的例子:

     1 function operation(left,right,op){
     2     function add(){
     3         return left + right;
     4     }
     5     function minus(){
     6         return left - right;
     7     }
     8     function multiple(){
     9         return left*right;
    10     }
    11     function divide(){
    12         return left/right;
    13     }
    14     if (op=="+") print (add());
    15     else if (op=="-") print (minus());
    16     else if (op=="*") print (multiple());
    17     else if (op=="/") print (divide());
    18     else print ("Invalid operation.");
    19 }

      对于示例代码,我们可以发现,内嵌函数可以访问外部函数的参数、全局变量等。

      在调用函数时,通常是没有办法直接访问内嵌函数的。

      4.3 函数调用的机制

      JavaScript使用栈和上下文的机制来调用函数,我们可以将JavaScript执行时的每一行代码的顺序看做是上下文,并且使用栈来存储上下文。

      当我们调用一个方法时,在调用前,栈会保存当前上下文,然后调用函数,在调用结束后,栈会从之前保存过的上下文开始继续执行。

      如果上下文增长过快,会导致堆栈溢出,例如当我们在A方法中调用B方法,然后在B方法中调用A方法,这种循环调用的方式很容易就将堆栈搞坏了。

      4.4 函数作为值的处理

      在JavaScript中,函数也是一种值,这是和其他语言不太一样的。

      来看下面的代码:

    1         var a=false;
    2         function test(){
    3             print("test");
    4         }
    5         
    6         (a||test)();
    7         
    8         var b=test;
    9         b();

      如果要理解“函数都是值”的意思,我们可以从某种程度上认为b是一个函数指针,它指向了test函数。

      4.5 闭包

      JavaScript中的闭包是指函数的返回值是一个函数,并且返回值函数使用了外部函数的变量(参数或者局部变量)。

      对于嵌套函数来讲,它可以访问外部函数的参数或者局部变量,示例如下:

     1         function foo(x){
     2             var y=1;
     3             function bar(z){
     4                 y=y+1;
     5                 print(x+y+z);
     6             }
     7             bar(1);
     8         }
     9 
    10         foo(1);

      在这里,嵌套函数bar访问了外部函数foo的参数x及局部变量y,并且对y有加1的操作,但这不叫闭包,我们多次调用foo(1),并没有使得y递增。

      下面才是闭包:

     1         function foo(x){
     2             var y =1;
     3             return function(z){
     4                 y = y+1;
     5                 print(x+y+z);
     6             }
     7         }
     8         
     9         var bar=foo(1);
    10         bar(1);

      我们可以看到上面代码中foo的返回值本身就是一个匿名函数,如果我们多次调用bar(1),可以发现foo函数的局部变量y的值是一直在递增。

      闭包在实际的应用中,一般是用来封装对复杂数据结构的各种操作,从而对外提供简单易用的接口,用户在使用时不用太关心闭包内部的实现细节。

      4.6 函数的可变参数

      JavaScript在调用函数时,并不会限制传入参数的个数,当传入参数的个数多于函数定义中参数的个数时,多余的参数会被忽略;当传入参数的个数小于函数定义中参数的个数时,缺失的参数默认是undefined。

      我们来看下面的例子:

     1 function argumentTest(v1,v2,v3,v4){
     2     print(v1+v2+v3+v4);
     3 }
     4 
     5 //调用方法
     6 argumentTest(1,2,3);
     7 argumentTest(1,2,3,4,5);
     8 
     9 
    10 //输出结果
    11 NaN
    12 10

      可以看到,当我们给出的参数有缺失时,默认的undefined和其他参数做运算时,返回了NaN。当我们给出的参数有富余时,被自动忽略了。

      在JavaScript中,函数中有默认的一个变量,名为arguments在这里,arguments并不是一个数组,typeof arguments返回的是object),它用来保存所有传入的参数,我们来看下面的例子:

     1 function argumentTest(v1,v2,v3,v4){
     2     var result=0;
     3     for(var i = 0; i < arguments.length;i++){
     4         result=result+arguments[i];
     5     }
     6     print(result);
     7 }
     8 
     9 //调用方法
    10 argumentTest(1,2,3);
    11 argumentTest(1,2,3,4,5);
    12 
    13 //执行结果
    14 6
    15 15

      这里我们可以看到,无论我们传入了多少参数,都可以被适当的处理了。

  • 相关阅读:
    LeetCode0350.两个数组的交集 II
    LeetCode0055.跳跃游戏
    LeetCode0739.每日温度
    LeetCode面试题46.把数字翻译成字符串
    LeetCode0128.最长连续序列
    LeetCode面试题29.顺时针打印矩阵
    LeetCode0238.除自身以外数组的乘积
    2020软件工程最后一次作业
    如何防止XSS攻击
    需求规格说明书
  • 原文地址:https://www.cnblogs.com/wing011203/p/3175463.html
Copyright © 2020-2023  润新知