(一)JavaScript基础语法和数据类型

本文介绍了JavaScript的基础知识,包括语言的历史背景、基本语法、数据类型、流程控制等内容,适合初学者快速掌握JavaScript编程。

一、概述

1.1、前言

  • JavaScript是世界上最流行的脚本语言,在电脑、平板、手机上浏览的所有网页,以及基于HTML5的手机APP,交互逻辑都是由JavaScript驱动的。
  • JavaScript就是一种运行在浏览器中的解释型的编程语言。
  • 在Web开发中,只有JavaScript能跨平台、跨浏览器驱动网页,与用户交互。
  • 而JavaScript出了语法上有点像Java,其他部分基本上没啥关系。

1.2、ECMAScript

  • 为了让JavaScript成为全球标准,几个公司联合ECMA(European Computer Manufacturers Association)组织制定了JavaScript语言的标准,被称为ECMAScript标准(由于JavaScript是网景公司注册的商标,所以不能用来作为标准)。
  • ECMAScript其实就是一种语言标准,而JavaScript是网景公司对ECMAScript标准的一种实现。
  • 如果你遇到了ECMAScript这个词,简单把它替换为JavaScript就可以了。

1.3、JavaScript版本

  • 由于JavaScript的标准——ECMAScript在不断发展,最新版ECMAScript6标准(简称ES6)已经在2015年6月正式发布了。所以讲到JavaScript的版本,实际上就是说它实现了ECMAScript标准的哪个版本。
  • 但是由于浏览器在发布时就确定了JavaScript的版本,加上很多用户还在使用IE6这种古老的浏览器,这就导致你在写JavaScript的时候,不能一上来就用最新的ES6标准写,否则IE6这种用户的浏览器是无法运行最新版本的JavaScript代码的。

二、第一个JavaScript程序

2.1、引入JavaScript

引入JavaScript有内部标签和外部引入两种方式。

内部标签

JavaScript代码可以嵌在网页的任何地方,不过我们通常把JavaScript代码放在<head></head>标签中。

<html>
<head>
	<script>
		alert('Hello, world');
	</script>
</head>
<body>
...
</body>
</html>

<script></script>包裹的代码就是JavaScript代码,它将直接被浏览器执行。

外部引入

外部引入就是把JavaScript代码放到一个单独的.js文件中,然后在HTML中引入这个文件。

<html>
<head>
	<!-- 注意:script标签必须成对出现 -->
	<script src="js/abc.js"></script>
</head>
<body>
...
</body>
</html>

<script></script>标签中的src属性值就是.js文件的路径。这样js/abc.js就会被浏览器执行。

  • 把JavaScript代码放入一个单独的.js文件中更利于维护代码,并且多个页面可以各自引用同一份.js文件
  • 可以在同一个页面中引入多个.js文件
  • 还可以在页面中多次编写<script></script>标签的代码,浏览器按照顺序依次执行
  • 有时可能会看到<script></script>标签中设置了一个type属性,但这是没必要的,因为默认的type就是text/javascript,所以不需要显式地把type指定为JavaScript
	<script type="text/javascript"></script>

2.2、运行JavaScript

要让浏览器运行JavaScript,必须有一个HTML页面,在HTML页面中引入JavaScript,然后让浏览器加载该HTML页面,就可以执行JavaScript代码。

如果直接在硬盘上创建好HTML和JavaScript文件,然后用浏览器打开。这种方式运行部分JavaScript代码没问题,但由于浏览器的安全限制,以fttp://开头的地址无法执行如联网等JavaScript代码。

所以还是需要架设一个web服务器,然后以http://开头的地址来正常执行所有JavaScript代码。

<html>
<head>
	<script>
		// 注释
		/* 注释 */
		alter("Hello, JavaScript");
	</script>
</head>
<body>
...
</body>
</html>

浏览器将弹出一个对话框,显示Hello, JavaScript

2.3、调试

如何在浏览器中调试代码?
F12打开浏览器调试工具,点击Console(控制台),在这里输入JavaScript代码,按回车运行。
比如要查看一个变量a的值,在Console中输入console.log(a);,回车后显示的就是变量的值。

三、快速入门

3.1、基本语法

JavaScript的语法和Java相似,每个语句以;结束,语句块用{...}
其实JavaScript并不强制要求在每个语句结尾加上 ;,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上 ;
但是JavaScript引擎自动加分号在某些情况下会改变程序的语义,导致运行结果与期望不一致。所以尽量不要省略 ;

  1. 普通赋值

    var x = 1;
    
  2. 代码块

    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- JavaScript严格区分大小写 -->
    <script>
        // 1、定义变量  变量类型 变量名 = 变量值;
        var num = 1;
        var name = "new";
        // 2. 条件控制
        if (2 > 1) {
            alert("true");
        }
    
        console.log(name);// 在浏览器的控制台打印变量,相当于sout
    </script>
    </head>
    <body>
    </body>
    

3.2、数据类型和变量

数值,文本,图形,音频,视频等都属于数据类型。

  1. Number
    js不区分浮点数和整数,统一用Number表示。

    123;// 整数123
    123.1;// 浮点数123.1
    1.23e3;// 科学计数法
    -99; // 负数
    NAN; // not a number,一个不是数字的数字类型。当无法计算结果时用NaN表示
    Infinity; // 表示无限大。当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity
    

    Number还可以进行四则运算

    1 + 2; // 3 
    (1 + 2) * 5 / 2; // 7.5 
    2 / 0; // Infinity 
    0 / 0; // NaN 
    10 % 3; // 1 
    10.5 % 3; // 1.5
    
  2. 字符串
    字符串是以单引号或双引号括起来的任意文本。

    'abc';
    "abc";
    
  3. 布尔值

    true;
    false;
    2 > 1; // 这是一个true值
    2 < 1; // 这是一个false值
    
    // 逻辑运算
    && // 与:只有都为true时,结果才为true
    || // 或:只要有一个为true,结果就是true
    ! // 非:把true变为false,把false变为true
    
    true && false; // 结果为false
    true || false; // 结果为true
    !true; // 结果为false
    
  4. 比较运算符
    当我们对Number作比较时,可以通过比较运算符得到一个布尔值

    2 > 5; // false
    5 > 2; // true
    false == 0; // true
    false === 0; // false
    =    赋值
    ==   等于(类型不一样,值一样,也会判断为true===  绝对等于(必须类型一样,值一样才会为true

    ==是JS的一个缺陷,尽量不要使用==比较

    NaN===NaN; // false
    /*
    	NaN与所有的数值都不相等,包括自己
    	只能通过isNaN(NaN)函数来判断这个数是否是NaN
    */
    

    特别注意浮点数的相等比较:

    console.log((1/3)===(1-2/3)); // false
    

    浮点数在运算过程中会产生误差,因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等,只能计算他们之差的绝对值,看是否小于某个阈值。

    Math.abs(1 / 3 - (1 - 2 / 3)) < 0.000001; // true
    
  5. null和undefined

    null // 表示一个空的值
    undefined // 表示值未定义,只在判断函数参数是否传递的情况下有用
    
  6. 数组
    Java的数组必须是一系列相同类型的对象,JS中不需要这样

    var arr = [1,2,3,4,5,'hello',null,true];
    

    数组用[ ]表示,元素之间用,分隔。数组的元素可以通过索引来访问。

    arr[0]; // 返回的为索引为0处的1
    
  7. 对象
    JavaScript中的对象是由一组键值对组成的无序集合,如:

    var person = {
        name: "zhang",
        age: 3,
        tags: ['js', 'java']
    }
    

    JavaScript的键都是字符串类型,值可以是任意的数据类型。其中每个键又称为对象的属性,如person的name属性为'张'
    如果需要获取一个属性的值,可以使用对象变量名.属性名的方式

    person.name; // "zhang"
    person.age; // 3
    

3.3、严格检查模式——strict

JavaScript在设计之初,并不强制要求用var声明变量。这个设计带来了严重的后果:如果一个变量没有通过var声明就被使用,那么该变量就自动被声明为全局变量。

i = 10; // i现在是全局变量

在同一页面的不同JavaScript文件中,如果都不用var声明,恰好都使用了变量i,将会造成变量间相互影响,产生错误。
使用var声明的变量则不是全局变量,它的范围被限制在该变量被声明的函数体内,同名变量在不同的函数体内不冲突。
为了修复这一严重缺陷,ECMA在后续的规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var声明变量,没有使用var的会导致运行错误。
启用strict模式的方法是在JavaScript代码的第一行写上:

'use strict';
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--
    前提:IDEA需要支持ES6语法
    严格检查模式,预防JavaScript 的随意性导致产生的一些问题
    必须写在 JavaScript 的第一行
    局部变量建议都是用 let 定义
    -->
    <script>
    	'use strict';
        // 全局变量,加上 var 以后就是局部变量
        i = 1;
        // ES6中 使用 let 标识局部变量
    </script>
</head>

3.4、字符串

' '" "括起来的就是字符串。
如果'本身也是一个字符,可以用" "括起来。比如:

"I'm OK";

包含的字符是I,’,m,空格,O,K这个六个字符。
如果字符串内部既包含'又包含",可以使用转义字符\来标识,比如:

'I\'m \"OK\"!';

表达的内容就是:I’m OK!

  1. 转义字符

    \ ’ ’
    \n 换行
    \t table
    \u4e2d \u### Unicode字符 中
    \x41 Ascll字符

  2. 多行字符串编写
    // 使用table键上面的~,将多行字符串包裹
    var msg = `
    hello
    world
    你好
    你好~
    `
    
  3. 模板字符串
    相当于+
    // table键上面的~
    let name = "zhang";
    let age = 3;
    let msg = `你好呀,${name}`;
    console.log(msg); // 你好呀,zhang
    
  4. 操作字符串
    字符串的常见操作如下:
    (1)获取字符串的长度
    var student = "student";
    console.log(student.length)
    
    (2)获取字符串某个指定位置的字符
    // 类似于Array的下标取值操作,从0开始
    var s = 'Hello world!';
    s[0]; // 'H'
    s[1]; // 'e'
    s[12]; //undefined,超出范围的索引不会报错,一律返回undefined
    
    需要注意的是:字符串是不可变的,如果对字符串的某个索引赋值,不会报错,但也不会有任何效果
    var s = 'Test';
    s[0] = 'X';
    alert(s); // s仍然为Test
    
    所以JavaScript为字符串提供了一些常用方法。需要注意的是:调用这些方法本身不会改变原有字符串的内容,而是会返回一个新的字符串。
    (3)字符串大小写转换
    // 注意:这里调用的是方法不是属性
    // 把一个字符串全部变为大写
    var student = "student";
    console.log(student.toUpperCase()); // STUDENT
    
    // 把一个字符串全部变为小写
    var student = "STUDENT";
    console.log(student.toLowerCase()); //student
    
    (4)获取字符串中指定字符第一次出现位置的下标
    var student = "student";
    console.log(student.indexOf('t'));// 返回结果为1,如果没有则返回-1
    
    (5)返回指定索引区间的子串
    var student = "student";
    // 包前不包后
    console.log(student.substring(0, 3))
    

3.5、数组

JavaScript的数组可以包含任意数据类型,并通过索引来访问元素。

var arr = [1,2,3,4,5]; // 通过下标取值和赋值
arr[0];
arr[0] = 1
  1. 如果要获取Array的长度,直接访问length属性
    var arr = [1, 2, 3.14, 'Hello', null, true];
    arr.length; // 6
    
    注意:如果给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失
    var arr = [1, 2, 3];
    arr.length; // 3
    arr.length = 5;
    arr; //变为[1, 2, 3, undefined, undefined]
    arr.length = 2;
    arr; // [1, 2]
    
  2. Array可以通过索引把对应的元素修改为新的值
    var arr = ['A', 'B', 'C'];
    arr[1] = 99;
    arr; //['A', 99, 'C']
    
    注意:如果通过索引赋值时,索引超出了范围,同样会引起Array的变化
    	var arr = ['A', 'B', 'C'];
    	arr[4] = 99;
    	arr; //['A', 'B', 'C', undefined, 99]
    

注意:大多数编程语言不允许直接修改数组的大小,越界访问会报错。而JavaScript的Array不会有任何错误。所以在编写代码时,不建议直接修改Array的大小,访问索引时要确保索引不会越界。

  1. 与字符串类似,Array也可以通过indexOf()来搜索一个指定元素的位置

    var arr = ['A', 'B', 'C'];
    arr.indexOf('B'); // 1
    arr.indexOf(5); // 如果没有找到,返回-1
    
  2. 截取Array的一部分,返回一个新数组,类似于String中的subString

    var arr = ['A', 'B', 'C', 'D', 'F', 'E'];
    arr.slice(0, 3); //从索引0开始,到3结束,但不包括3。['A', 'B', 'C']
    arr.slice(3); // 从索引3开始,一直到末尾。 ['D', 'F', 'E']
    

    如果不给slice()传参,它就会从头到尾截取所有元素。可以利用slice()来复制一个新的数组。

    var arr = ['A', 'B', 'C', 'D', 'F', 'E'];
    var arr2 = arr.slice(); 
    arr2 === arr; // false
    
  3. 操作尾部元素

    /*
    	push:将数据添加至尾部
    	pop:弹出尾部的元素
    */
    var arr = [1, 2];
    arr.push('A', 'B'); // 返回Array的新长度:4
    arr; // [1, 2, 'A', 'B']
    arr.pop(); // pop()返回'B'
    arr; // [1, 2, 'A']
    arr.pop().pop().pop(); //连续 pop 三次
    arr; // []
    
  4. 操作头部元素

    /*
    	unshif:将数据添加至头部
    	shif:弹出头部的元素
    */
    var arr = [1, 2];
    arr.unshif('A', 'B'); // 返回Array的新长度:4
    arr; // ['A', 'B', 1, 2]
    arr.shif(); // shif()返回'A'
    arr; // ['B', 1, 2]
    arr.shif().shif().shif(); // 连续 shif 三次
    arr; // []
    
  5. Array排序
    sort()可以对当前Array排序,它会直接修改当前Array的元素位置,直接调用时,按照排序方式

    var arr = ['C', 'B', 'A'];
    arr.sort();
    arr; // ['A', 'B', 'C']
    

    在后面的函数会讲到如何自定义排序方式。

  6. 元素反转
    会把Array的元素交换位置。

    var arr = ['C', 'B', 'A'];
    arr.reverse();
    arr; // ['A', 'B', 'C']
    
  7. splice():可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素

    var arr = ['A', 'B', 'C', 'D', 'F', 'E'];
    arr.splice(2, 3, 'H'); // 从索引2开始删除3个元素,再添加'H'
    arr; // ['A', 'B', 'H', 'E']
    arr.splice(2, 2); // 只删不加
    arr; // ['A', 'B']
    arr.splice(1, 0, 'Z'); // 只加不删
    arr; // ['A', 'B', 'Z']
    
  8. 拼接数组,并返回一个新的数组

    var arr = ['A', 'B', 'C'];
    var arrAdd = arr.concat([1, 2, 3]);
    arrAdd; // ['A', 'B', 'C', 1, 2, 3]
    

    concat()方法可以接收任意个元素和Array,并且自动把Array拆开,全部添加到新的Array

    var arr = ['A', 'B', 'C'];
    var arrAdd = arr.concat(1, [2, 3]);
    arrAdd; // ['A', 'B', 'C', 1, 2, 3]
    
  9. 连接符,打印拼接数组,使用指定的字符串连接数据内任意数据类型的元素

    var arr = ['A', 'B', 'C'];
    arr.join('-'); // A-B-C
    
  10. 多维数组。如果某个数组的元素是一个数组,则可以形成一个多维数组

    arr = [[1,2],[3,4],["5","6"]];
    arr[0][1]; // 2
    

3.6、对象

JavaScript的对象是一种无序的集合数据类型,由若干个键值对组成。

  1. 定义一个对象
    /* 
    在JS中,使用{...}示一个对象,键值对描述属性xxx: xxx
    多个属性之间使用逗号隔开,最后一个属性不加逗号
    */
    var person = {
    	属性名: 属性值,
    	属性名: 属性值,
    	属性名: 属性值
    }
    
    var person = {
        name: "zhang",
        age: 3,
        email: "123456@qq.com"
    }
    
  2. 获取对象的属性
    // 对象.属性
    var person = {
        name: "zhang",
        age: 3,
        email: "123456@qq.com"
    }
    person.name; // 'zhang'
    
  3. 由于JavaScript的对象是动态类型,所以可以自由地给一个对象添加或删除一个属性
    var person = {
        name: "zhang"
    }
    person.age; //undefined
    person.age = 3; // 新增一个age属性
    person.age; // 3
    
    delete person.age; // 删除一个属性。如果被删除的属性不存在,也不会报错
    person.age; //undefined
    
  4. 判断对象中是否存在某一属性
    var person = {
        name: "zhang",
        age: 3,
        email: "123456@qq.com"
    }
    age in person; //true
    grade in person; // false
    // 注意:如果用 in 判断到一个属性存在,这个属性不一定是这个对象的,有可能是这个对象继承得到的
    toString in person; // true
    
  5. 判断一个属性是否是这个对象自身拥有的
    因为toString定义在object对象中,而所有对象最终都会在原型链上指向object
    如果要判断一个属性是否是自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法
    var person = {
        name: "zhang",
        age: 3,
        email: "123456@qq.com"
    }
    person.hasOwnProperty(age); //true
    person.hasOwnProperty(toString); // false
    

3.7、流程控制

  1. if 判断
    var a = 3;
    if (age > 3) {
        alert("haha");
    }else {
        alert("kuwa");
    }
    
  2. for循环
    (1)基本语法
    for (let i = 0; i < 100 ; i++) {
        console.log(i);
    }
    
    (2)遍历数组
    var arr = [1,2,3,4,5];
    for (let i = 0; i < arr.length ; i++) {
        console.log(arr[i]);
    }
    
    (3)for…in,可以把一个对象的所有属性依次循环出来
    var person = {
        name: "zhang",
        age: 3,
        email: "123456@qq.com"
    }
    for(var key in person) {
        if (person.hasOwnProperty(key )) {
    	    console.log(key); // 'name', 'age', 'email'
    	}
    }
    
    由于Array也是对象,而它的每个元素的索引被视为对象的属性,所以遍历出来是下标
    var ages = [1,2,3];
    for(var num in ages) {
        if (age.hasOwnProperty(num)) {
        	console.log(age); // '0', '1', '2'
    	    console.log(age[num]); // '1', '2', '3'
    	}
    }
    
    注意:for...inArray循环得到的是String而不是Number
    (4)forEach循环
    var ages = [1,2,3,4,5,6];
    ages.forEach(function (value) {
        console.log(value);
    });
    
  3. while循环
    age = 0;
    while (age < 100) {
        age = age + 1;
        console.log(age);
    }
    
  4. do…while
    age = 0;
    do{
        age = age + 1;
        console.log(age);
    }while(age < 100)
    

3.8、Map和Set

MapSet是ES6规范引入的新的数据类型

  1. Mapkey-value的键值对形式存储数据。初始化的时候需要一个二维数组,或者直接初始化一个空。
    // 学生的名字,学生的成绩
    var map = new Map([['tom',100],['jack',90],['haha',80]]);
    var score = map.get('tom'); // 通过key获得value
    map.set('admin',123456); // 添加键值对
    map.delete('tom');  // 删除键值对
    
    Map中一个key只能对应一个value,所以多次对同一个key放入value,只会保存最后一次放入的值。
  2. Set。无序不重复的集合。
    var set = new Set([3,1,1,1]);  // set中的重复元素会被过滤
    set.add(2);  // 添加
    set.delete(1);  // 删除
    console.log(set.has(3));  // 是否包含某个元素
    

3.9、Iterator

遍历Array可以采用下标循环,遍历MapSet就无法使用下标。
所以ES6标准引入了iterator类型。
具有iterator类型的集合可以通过新的for...of循环来遍历。

  1. 遍历数组
    // 通过for of 实现     for in获取下标
    var arr = [3,4,5];
    for (var x of arr) {
        console.log(x);
    }
    
    var arr = [3,4,5];
    arr.name = "213";  // 早期的漏洞,for...in打印下标时会把新增的这个name也打印出来
    for (let x in arr) {
        console.log(x)
    }
    
  2. 遍历Map
    var map = new Map([["tom", 100],["jack", 90],["haha", 80]]);
    for (let x of map) {
        console.log(x[0] + '=' + x[1]);
    }
    
  3. 遍历Set
    var sett = new Set([5,6,7]);
    for (let x of sett) {
        console.log(x)
    }
    
    更好的方式是直接使用iterator内置的foreach方法。
  4. 遍历数组
    var arr = [3,4,5];
    a.forEach(function (element, index, array) {
    	 // element: 指向当前元素的值 
    	 // index: 指向当前索引 
    	 // array: 指向Array对象本身 
    	 console.log(element + ', index = ' + index); 
     });
    
  5. 遍历Set
    var s = new Set(['A', 'B', 'C']);
    s.forEach(function (element, sameElement, array) {
    	 // 由于set没有索引,所以回调函数的前两个参数都是元素本身
    	 console.log(element + ', index = ' + index); 
     });
    
  6. 遍历Map
    var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
    m.forEach(function (value, key, map) {
    	 console.log(value); 
     });
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值