JavaScript基础知识

本文为笔者所整理的学习js的笔记

正文

Js基础概念与引导

1. js是一种动态,编译的弱类型语言
2. js变量是没有类型的,但是值有类型

因而我们声明一个变量统一用“var”关键字来声明。但是放进该变量中的值却有其类型,具体类型在第二部分会详细介绍。例如
var a = 123;//变量a声明时赋初值为数字123
a = "string";//变量a同时也可被赋值为字符串“string”

3. js没有动态作用域。此问题具体解释有些复杂,且不太了解对于现在所学影响不大,因而推荐几篇解释较好的文章,可自行阅读

链接如下:
http://m.blog.csdn.net/article/details?id=53131411
http://www.ituring.com.cn/tupubarticle/3482

4. javascript与java完全不同

由于javascript以java开头,许多未接触过javascript的同学会误以为二者之间有着一定的关联,其实不然,二者之间没有必然联系,其核心理念完全不同:

javascript不鼓励多态

所谓多态即同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。最常见的实现方式比如重载:多个同名方法但参数不同,通过不同参数可以调用不同的方法。

javascript面向委托,面向原型

多态是面向对象程序设计的一个重要特性,javascript不鼓励多态,因而我们很难认为它是一门面向对象的编程语言。它其实是一门面向委托,面向原型的编程语言


Js基础语法

在学习语法之前,我们需要知道,HTML文件中如何调用javascript,以下有两种方式:

  • 在HTML文件中通过<script></script>标签调用标签之间为javascript代码
  • 通过文件调用
    将所需javascript代码用纯文本编辑器写入文件保存为后缀.js文件,在<head></head>标签中通过以下代码引用*.js文件
    <script src="/*.js文件地址*/" type="text/javascript"></script>
  • 此外值得一说的是,js语句以结尾,如果没有游览器在解释时会自动添加,并不会报错,但是我们需要养成一个好的代码习惯,以作为语句的结尾

    输入与输出

    首先我们需要明确一点:游览器js没有办法直接进行文件io,也没有scanf()此类输入输出方法。能够进行文件输入输出的是 node.js,其与我们所学习的不同,因此在此我们暂且不进行研究。

    但是我们依旧能够使游览器进行一些简单打印操作,以下介绍四种常用方法:

  • 1. document.write()
  • <script>
        document.write("hello world!");
    </script>

    此方式使用时需要注意!其会清空文档流在游览器界面中打印“hello world!”
    即你可能会发现调用该方法后原本游览器文档被清空,只打印了你需要输出的文档

  • 2. console.log()
  • <script>
        console.log("hello world!");
    </script>

    此方法是最为常用的输出及代码调试方法, 其在游览器控制台进行输出效果如下:

  • 3. alert()
  • <script>
        alert("hello world!");
    </script>

    此方法是常见的输出方式,调用此方法,将在游览器中弹出一个通知窗口,打印“hello world!”

  • 4. confirm()
  • <script>
        confirm("hello world!");
    </script>

    此方法与alert()相似,调用此方法,将在游览器中弹出一个通知窗口,打印“hello world!”。
    与alert()不同的是该通知窗口有两个选项确认取消,点击确认将会返回一个true值,点击取消将返回false值

    变量和值

    js的变量是没有类型的,但是值有类型,具体类型一共有7种,接下来将分别对其进行介绍说明

    • null
      表示为空

    • undefined
      该值的类型为js特有,表示未定义,其与null基本没有区别,细微之处的不同推荐一篇文章
      http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html

    • boolean
      只有两种值:true & false 常用于判断真假

    • number
      表示数字,上界为js中的Number.MAX_VALUE常量,你可以通过console.log(Number.MAX_VALUE);语句,通过控制台查看其值

    • string
      字符串类型的值,如"abc"

    • object
      对象,可以自己声明以及定义,下文将对其详细介绍

    • Symbol//ES6新增

    js变量声明

    • js变量声明,由于变量没有类型,我们统一使用var关键字进行变量声明,其语法规则如下:

      • 变量必须使用字母、下划线_$开始。
      • 然后可以使用任意多个英文字母、数字、下划线_$组成。
      • 不能使用js关键词与保留字。
    • 变量必须先声明后使用
      注意:

      js区分大小写。如变量score与Score是不一样的,相当两个变量。

      变量虽然可以不声明,直接使用,但不规范,会涉及变量名提升等问题,并且出于好的代码习惯考虑, 变量使用之前请先声明。

    js的内置对象

    首先明确一下对象的定义:

    对象只是带有属性和方法的特殊数据类型
    属性是与对象相关的值
    方法是能够在对象上执行的动作

    在js里,一切皆为或者皆可以被用作对象。可通过new一个对象或者直接以字面值形式创建变量,所有变量都有对象的性质

    js内置了几类对象

    • String
      String中的方法用于字面值为string的变量的操作,例如:
    <script>
        var st = "hello";
        console.log(st.length);
    </script>

    此代码在实际执行时相当于执行了以下代码

    <script>
        var st; 
        st = new String("hello"); //st 被包装成一个String对象
        console.log(st.length);
    </script>

    此段代码中,st被暂时包装成一个String对象,可调用String对象的属性和方法,但是注意,这并不意味这st就是一个对象了,在方法调用完毕之后它会被立即解封。

    String 类定义了大量操作字符串的方法,例如从字符串中提取字符或子串,或者检索字符或子串。

    需要注意的是,JavaScript 的字符串是不可变的,String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串:

    <script>
        var st="hello";
        console.log(st.toUpperCase());
        console.log(st);
    </script>

    控制台输出如下:

    HELLO
    hello

    我们很容易发现,在调用了toUpperCase后st内的值依旧是“hello”而非“HELLO”,这便是我们所说的不可变,并非说st内的值不能改变,赋值即可改变其值

    • Number
      与String对象相似,Number中的方法用于字面值为number类型的变量的操作,其调用方法的过程与String相似,在此不再赘述,介绍几个常用方法,例如:

    toString()方法把数字转换为字符串

    <script>
        var num = 123;
        console.log(num.toString());
    </script>

    toFixed()方法将数字转换为字符串,结果的小
    数点后有指定位数的数字

    <script>
        var num = 123.333;
        console.log(num.toFixed(2));
    </script>

    输出:
    123.33

    并且
    js中本身没有整数与浮点数之分,所谓整数,不过是没有小数部分的浮点数

    • Array
      Js中的数组对象非常灵活,相较于String的不可变性来说,它是可变的,大多数时候,调用方法都是对其原值进行的修改。

      数组对象用来在单独的变量名中存储一系列的值,因而它储存的是值,而非数字,所以,我们上文所提到的字面值的所有类型都可以作为数组的值,并且出现在同一个数组中。

    数组声明:

    数组对象是动态的,声明数组时可以不事先声明长度,我们有以下几种方式来声明一个数组对象:

  • 1
  • <script>
        var myArray=new Array(); //声明了一个叫做myArray的数组,未规定其容量
    </script>

  • 2
  • <script>
        var myArray = new Array(3);//声明了一个的数组,规定其容量为3
    </script>

    元素访问

    数组中元素的访问可以通过下标访问,即例如:myArray[0] = “123”;
    常用方法:

  • 1. 合并两个数组 - concat()
  • 2. 用数组的元素组成字符串 - join()
  • 3. sort()
    数组对象本身有排序方法sort()
  • 使用方法如下:

    <script>
        var myArray = new Array();
        myArray = [10,19,44,11,345,1000002];
        console.log(myArray.sort());
    </script>

    控制台输出结果如下:
    [10,1000002,11,19,345,44]

    我们可以发现,期排序结果并非如我们所想数字按照升序排列,原因是sort()方法默认的是按照字典序排序
    我们可以按需要自定义方法使其对数字按大小进行升序排序,操作如下:

    <script>
        var myArray = new Array();
        function sortNumber(a, b)
        {
            return a - b;
        }
        myArray = [10,19,44,11,345,1000002];
        console.log(myArray.sort(sortNumber));
    </script>

    我们自定义了一个sortNumber函数将其作为参数传入sort()方法,从而达到对数字进行升序排序的目的

  • 4. Function
  • 函数在js中也是一种对象,下文会对其有着重介绍。

  • 5. Boolean
  • 6. Date
  • 该对象主要包含大量对于日期,时间的调用以及修改的方法

  • 7. RegExp
  • 8. Error
  • 9. Object
  • 函数声明

    函数在js中本质上是一种对象,而且其在js中的地位相当于“一等公民”

    对于js中的函数声明,我们有三种常见方法:

    • 通过“var”关键字声明
    var add = function (a,b){
        return a+b;
    };

    以上代码,声明了一个名叫add的函数,其中function是关键字;

    • 直接通过“function”关键字声明
    function add (a,b){
        return a+b;
    }

    以上代码,声明了一个名叫mul的函数。
    以上两种声明方式声明函数,效果看似相近,实则有着很大的不同。
    我们通过如下代码来进行分析:

    <script>
        console.log(mul(1,2));
        console.log(add(1,2));
        var add = function (a,b){
            return a+b;
        };
        function mul (a,b){
            return a*b;
        }
    </script>

    结果如下:

    2
    Uncaught TypeError: add is not a function at <anonymous>:2:17

    我们可以发现,同样是将函数调用放在了函数声明之前,但是用function声明的函数依旧能够正常运行,而用var声明的函数却报错了。
    这是因为在游览器解释代码时,游览器会自动将var 声明的变量名提前至<script>标签内部顶端,但是未提前函数声明,因而,调用函数时报错了;而用function声明的函数,游览器会将其整个函数声明提前至<script>标签内部顶端,因此,调用函数能够正常运行。

    • 匿名函数&立即执行函数
    (function(){
        let result = 0;
        for(let i=~ 0;i<arguments.length;i++){
            result += arguments[i];
        }
       console.log(result);
    })(10,20,30,40);

    以上是一个匿名函数的声明,匿名函数没有直接声明函数名称
    匿名函数可以用作立即执行函数(IIFE)立即执行函数无需调用,直接执行。
    立即执行函数声明方式如下:

    (function(/*形参*/){/*……code……*/}(/*实参*/));立即执行函数
    (function(/*形参*/){/*……code……*/})(/*实参*/);立即执行函数

    值得一提的是:

    argument
    在js中arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。
    arguments非常类似Array,但实际上又不是一个Array实例,它存放的是函数的实参。
    arguments对象的长度是由实参个数而不是形参个数决定。

    let
    在js中,声明变量的方式除了var关键字声明之外,使用let关键字也可以声明,与var不同的是,let声明的变量具有局域性,变量只能在let所在的{}内部区域使用。

    以上三种函数的声明方式,各有各自优劣,我们均需要掌握,灵活运用。

    函数参数

    • 函数参数可以有默认值(ES6标准之前不被允许)
      例如下段代码:
    <script>
        (function (a,b,c=10) {
            console.log(a+b+c);
        })(1,2);
    </script>

    如果未对形参c传递实参,参数c的默认值为10。有默认值的参数只能出现在没有默认值参数的后面,就上例而言,我们可以令c有默认值,但是不能令b有默认值,而c没有;b,c同时被赋予默认值是被允许的。

    • js函数传参可以传递多于形参个数的实参
    <script>
        (function (a,b,c) {
            let sum = 0;
            for (let i = 0; i < arguments.length; i++) {
                sum += arguments[i];
            }
            console.log(sum);
        })(1,2,3,4);
    </script>

    控制台结果为:
    10

    以上函数我们只声明了3个形参,但是传递了4个参数,并且实际运行时,argument中有4个参数与了运算

    • js函数传参可以传递少于定义的个数的参数值
    <script>
        (function (a,b,c) {
            console.log(a+b);
        })(1,2);
    </script>

    以上函数我们声明了三个形参,但是实际仅传递了两个参数。

    函数参数还涉及到深拷贝与浅拷贝的问题,之后再进行学习

    JS 常用逻辑运算

    Js支持常用的逻辑运算

    三目运算符:
    var min = a > b ? a : b;

    条件语句:
    if...else...
    Switch...

    循环语句:
    for (let i=0;i<arguments.length;i++);
    while (/*判断*/){/*code*/}

    自定义对象

    Js中的对象,除了内置对象之外,还可以自定义对象。
    例如:

    var CS = {
        oneCourse : "data Structure",
        allClass : [1501, 1502, 1503, 1504, 1505]
    };
    
    var CS1501 = {
        teacher : "Chenyue",
        master : "Hemouren",
        studentNumber : 30,
        idcard : [1,2,3,4,5,6],
    
        addAll : function(){
            var result = 0;
            for (let i = 0; i < arguments.length; i++){
                result += arguments[i];
            }
            return result
        }
    };

    以上代码中,我们自定义了两个对象,一个名叫CS,另一个为CS1501

    我们定义对象依旧使用var来声明一个变量名,再将该变量赋值为一个对象

    基本方式如下:

    var /*对象名称*/ = {/*对象属性以及方法*/};

    对象的属性或者方法使用:运算符来声明。
    :左侧为属性或者方法的名字
    :右侧为属性或者方法的具体内容

    就对象CS1501而言
    teacherstudentNumberidcard均为其属性。其中teacher的值为字符串,idcard的值为一个数组,数组本身是一种内置对象,因此我们不难推断,js中对象之中还可以嵌套对象。而addAll则为CS1501的一个方法。

    对于对象中的属性或者方法,我们使用.运算符进行访问,例如:
    console.log(CS1501.studentNumber);

    js中我们可以将两个对象合并到一个对象中
    Object.assign(CS1501,CS);

    Object是一个内置对象,它其中包含了对于对象操作的方法
    Objec.assign(/*对象A*/,/*对象B*/);
    该方法能够将对象B中的元素拷贝到对象A

    • 深拷贝&浅拷贝
      在对于对象的学习中我们涉及到将一个对象拷贝到另一个对象之中的方法,我们从此可引出深拷贝与浅拷贝问题,如下例:
    Object.assign(CS1501,CS);
    CS1501.allClass[1] = "segmentfault";
    console.log(CS1501.allClass[1]);
    console.log(CS.allClass[1]);

    以上代码,将CS对象拷贝到CS501中,并将CS1501中的allClass[1]修改为"segmentfault"

    控制台的结果为:

    segmentfault
    segmentfault

    发现CS中的allClass[1]的值也为"segmentfault"
    再比如我们想备份一个Arrary或者String对象,用如下方式直接赋值

    <script>
        var arr = ["One","Two","Three"]
        var arrto = arr;
        arrto[0] = "segmentfault";
    </script>

    得到的结果是,arr[0]的值也随之修改了

    这是因为通过以上方式的对象拷贝为浅拷贝

    我们给出深拷贝与浅拷贝的解释:
    JavaScript存储对象都是存地址的,所谓浅拷贝会使得arr与arrto 指向同一块内存地址;而深拷贝会重新开辟一块内存,将被拷贝的对象所有属性以及方法一一复制过去。我们如果需要对于一个对象备份,需要一个一个将其属性复制过去
    如下图:

    arr储存方式:
    arr储存方式

    浅拷贝:
    浅拷贝

    深拷贝:
    深拷贝

    综合以上:
    我们如果需要对于一个对象备份(深拷贝),需要一个一个将其属性复制过去(如果对象中包含子对象或数组,我们则需要递归地进行复制)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值