JavaScript 基础

JavaScript

初识JavaScript

JavaScript 和 Java 是什么关系呢?
就是老婆和老婆饼的关系, 也就是没什么关系

JS 最初只是为了进行前端页面开发, 后来 JS 被赋予了更多的功能, 也可以用来开发桌面程序, 手机APP, 服务器端的程序

JS 和 Java 也有一些相同之处

在这里插入图片描述

  • HTML: 网页的结构(骨)
  • CSS: 网页的表现(皮)
  • JavaScript: 网页的行为(魂)

JS 是运行在浏览器上的, 比如 Chrome 里面就专门有一个模块, 就是JS引擎, 就相当于 JVM
一样, 能够解释执行 JS 代码. 后来就有大佬把这部分代码单独拿出来了,封装成独立的程序了, 称为 V8 引擎.
这样 JS 的使用范围也就更广了, 不在限于浏览器了.

JavaScript 的组成

  • ECMAScript(简称 ES): JavaScript 语法
  • DOM: 页面文档对象模型, 对页面中的元素进行操作
  • BOM: 浏览器对象模型, 对浏览器窗口进行操作

DOM API 是浏览器给JS提供的操作页面元素的 api
BOM API 是浏览器给JS提供的操作浏览器窗口的api

第一个程序

编写 hello world 程序

通过 Script 标签嵌入到 html 里面

<script>
        alert('hello world')
    </script>

在这里插入图片描述
三种引入方式

  1. 内部 js , 就是上面演示的 script 便签
  2. 外部 js 写成一个单独的 .js 文件
alert('hello world')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="app.js"> </script>
    <script>
        // alert('hello world')
    </script>
</body>
</html>

注释:
html: < !-- – >
css: /* */
js: // , /
* */

  1. 行内 js , 直接写到 html 元素内部
<body>
    <div onclick="alert('hello world')">
        这是一个div, 点我一下试试
    </div>

在这里插入图片描述


alert 能够弹窗, 从而让用户看到程序的输出, 但是弹框操作不太友好, 这个框弹出来就不能进行其他操作了, 这种框叫做 模态对话框.

我们使用 console.log 就可以在控制台中打印日志

<script>
        console.log('hello world');
    </script>

在这里插入图片描述

js 里这个 console.log 就类似 Java 中的 println 一样, 也是一个非常有用的调试手段.


语法

变量的使用

var 变量名 = 初始值;

<script>
        var a = 10;
        var b = 'hello'
        console.log(a)
        console.log(b)
    </script>

在这里插入图片描述
js 定义变量不必写类型, 不写类型不意味着"没有类型", 而是变量的类型是通过初始化操作的值来确定的.
上述的 a 就是 number 类型(JS 不区分 int double 同意都叫做 number)
b 就是 string 类型

JS 里定义变量使用的关键字还可以是 let
var 是老式的写法(可能有坑)
let 是新式写法, 规则更接近 C++ Java 等主流语言

  var a = 10;
  var a = 10;
  console.log(a);

在这里插入图片描述
这还是能够运行, 这就可能出现问题

如果用 let 就好了, 就能给你避免一些问题
在这里插入图片描述
细说还是有很多区别, 这里我们可不用纠结, 我们只要无脑用 let 就好了, 在别的地方见到 var 知道是啥就好了.

动态类型

  var a = 10;
  console.log(a)
  a = 'hello'
  console.log(a)

在这里插入图片描述

一个变量在程序运行过程中, 类型可以发生改变, 这就是动态类型(JS, Python, PHP…)
一个变量在程序运行过程中, 类型不能发生改变, 这就是静态类型(C++, Java,Go…)

动态类型的好处就是代码非常灵活
假如使用Java写两个数相加, 可能就得写多个方法, 用重载实现, 而动态类型的话写一个方法即可
坏处就是, 一个变量当下到底是啥类型, 里面存了什么值, 里面提供哪个方法哪些属性就是不确定的,

基本数据类型

JS 中内置的几种类型

  • number: 数字. 不区分整数和小数.
  • boolean: true 真, false 假.
  • string: 字符串类型.
  • undefined: 只有唯一的值 undefined. 表示未定义的值.
  • null: 只有唯一的值 null. 表示空值.
number 数字类型

JS 中不区分整数和浮点数, 统一都使用 “数字类型” 来表示.

var a = 07;    // 八进制整数, 以 0 开头
var b = 0xa;   // 十六进制整数, 以 0x 开头
var c = 0b10;   // 二进制整数, 以 0b 开头
string 字符串类型

基本规则
字符串字面值需要使用引号引起来, 单引号双引号均可

var a = "haha";
var b = 'hehe';
var c = hehe;   // 运行出错
转义字符

有些字符不方便直接输入, 于是要通过一些特殊方式来表示

  • \n
  • \
  • "
  • \t
求长度

使用 String 的 length 属性即可

var a = 'hehe';
console.log(a.length);
var b = '哈哈';
console.log(b.length);
字符串拼接

使用 + 进行拼接

var a = "my name is ";
var b = "zhangsan";
console.log(a + b);

注意, 数字和字符串也可以进行拼接

var c = "my score is ";
var d = 100;
console.log(c + d);

注意, 要认准相加的变量到底是字符串还是数字

console.log(100 + 100);   // 200
console.log('100' + 100);  // 100100

boolean 布尔类型

表示 “真” 和 “假”

boolean 原本是数学中的概念 (布尔代数).
在计算机中 boolean 意义重大, 往往要搭配条件/循环完成逻辑判断.

undefined 未定义数据类型

如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型

var a;
console.log(a)

undefined 和字符串进行相加, 结果进行字符串拼接

console.log(a + "10");  // undefined10

undefined 和数字进行相加, 结果为 NaN

console.log(a + 10);

null 空值类型

null 表示当前的变量是一个 “空值”.

var b = null;
console.log(b + 10);   // 10
console.log(b + "10");  // null10

运算符

JavaScript 中的运算符和 Java 用法基本相同.

这里说两个不一样的

  • === 比较相等(不会进行隐式类型转换)
  • !==
 let a = 10;
 let b = '10';
 console.log(a==b);
 console.log(a===b);

在这里插入图片描述
console.log(a==b); 这个代码中出触发了"隐式类型转换"

在 JS 中, 针对不同类型的值进行比较/运算, 会尝试尽可能转化为相同类型的值

console.log(a===b); 这个 === 就不会进行类型转换

像 Java 这种, 不太支持隐式类型转换的语言, 称为"强类型"语言
像 JS 这种, 比较能支持隐式类型转换的语言, 称为"弱类型"语言

数组

创建数组
使用 new 关键字创建

// Array 的 A 要大写
var arr = new Array();

使用字面量方式创建 [常用]

var arr = [];
var arr2 = [1, 2, 'haha', false]; // 数组中保存的内容称为 "元素"

注意: JS 的数组不要求元素是相同类型.

let arr3 = [1,2,3,4,5];
 console.log(arr3);
 arr3[0] = 6;
 console.log(arr3);

在这里插入图片描述
那我们要是打印超出数组范围的值呢?

 console.log(arr3[100]);
 console.log('还在继续执行');

在这里插入图片描述

    <script>
       let arr3 = [1,2,3,4,5];
        arr3[0] = 6;
        console.log(arr3);
        console.log(arr3[100]);
        arr3[100] = 666;
        console.log(arr3);
        arr3[-1] = 999;
        console.log(arr3);
        arr3['hello'] = 1234;
        console.log(arr3);
        console.log('还在继续执行');
     </script>

在这里插入图片描述
JS 的数组, 不仅仅是一个传统的数组了(只能按照下标取元素), 而是一个带有"键值对"性质的东西了.

数组的遍历

<script>
        let arr3 = [1,2,3,4,5];
        for(let i = 0; i < arr3.length; i++) {
            console.log(arr3[i]);
        }

        for(let elem of arr3) {
            console.log(elem);
        }

        for(let i in arr3) {
            console.log(arr3[i]);
        }
    </script>

给数组添加元素
使用 push 方法

arr3.push(666);

删除元素

splice

这个方法是一个万能方法
可以用来插入, 修改, 删除

splice(startIndex, count, 变长参数…)

把后面变长参数的内容, 替换到前面指定区间内
如果后面没有变长参数, 就相当于删除
如果后面变长参数和前面指定的区间个数一样, 此时就是修改/替换
如果后面变长参数比前面的区间个数常, 此时就是新增

    <script>
      let arr = [1,2,3,4,5];
       // 删除2下边开始的1个值
        arr.splice(2,1)
        console.log(arr);
        // 替换2下标的一个值
        arr.splice(2,1,666);
        console.log(arr);
        // 2下标插入一个值
        arr.splice(2,0,888);
        console.log(arr);
     </script>

在这里插入图片描述

函数

/ 创建函数/函数声明/函数定义
function 函数名(形参列表) {
  函数体
  return 返回值;
}
// 函数调用
函数名(实参列表)      // 不考虑返回值
返回值 = 函数名(实参列表)  // 考虑返回值
<script>
		function hello() {
            console.log('hello');
        }
        hello();
  </script>
 <script>
		 function add(x,y) {
            return x + y;
        }
        let a = add(3.5, 9);
        console.log(a);
</script>

函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次.

function hello() {
  console.log("hello");
}
// 如果不调用函数, 则没有执行打印语句
hello();

调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)

// 调用函数
hello();
// 定义函数
function hello() {
  console.log("hello");
}
<script>
		function add(x,y) {
            return x + y;
        }
        let a = add(3.5, 9);
        let b = add('hello','world');
        let c = add(true,2);
        let d = add(undefined,10);
        let e = add(undefined,'10');
        console.log(a);
        console.log(b);
        console.log(c);
        console.log(d);
        console.log(e);

    </script>

在这里插入图片描述

NaN 是not a number 的意思
如果实参个数少于形参个数, 多出来的形参的值就是 undefined
如果实参个数多余形参个数, 多出来的实参就没用上
实参和形参个数不匹配是不会报错的, 只会尽可能去执行.

支持n个参数的求和:

<script>
   		function add() {
           let result = 0;
           for (let elem of arguments) {
               result += elem;
           }
           return result;
       }

       let a = add(1,2,3,4,5);
       let b = add(3,5,6,7,8,9,0,5,3,2,5)
       console.log(a);
       console.log(b);
</script>

在这里插入图片描述

对于JS这样的动态语言来说, 不需要"重载" 这样的语法

函数表达式

<script>
 			let add = function() {
            let result = 0;	
            for (let elem of arguments) {
                result += elem;
            }
            return result;	
        }
</script>

先定义了一个没有名字的匿名函数, 然后把匿名函数赋值给一个 add 变量了.
add变量的类型, 就叫做 function 类型

<script>
			let add = function() {
            let result = 0;
            for (let elem of arguments) {
                result += elem;
            }
            return result;
        }
        // 获取变量的类型
        console.log(typeof(add));
</script>

在这里插入图片描述

JS 中, 可以像普通变量一样, 把函数赋值给一个变量,同时, 也可以把函数作为另一个函数的参数, 或者把函数作为另一个函数的返回值(这一点在Java是无法做到的)
这个特性, 称为在j s 中是"一等公民"

<script>
		function two() {
            return 100;
        }
        function one() {
            return two();
        }
</script>

JS 中变量的作用域

当代码中访问某个变量的时候, 要去哪里找这个变量呢?
JS 会先找到当前作用域, 如果当前没有, 就往上层作用域找, 一直往上找到全局作用域, 如果还找不到, 就报错/undefined

<script>
		let num = 1;
        function test1() {
        let num = 2;
        function test2() {
                let num = 3;
                console.log("test2: " +num);
            }
            test2();
            console.log("test1: " + num);
        }
        test1();
        console.log("global: " + num);
</script>

在这里插入图片描述

<script>
		let num = 1;
        function test1() {
        let num = 2;
        function test2() {
               // let num = 3;
                console.log("test2: " +num);
            }
            test2();
            console.log("test1: " + num);
        }
        test1();
        console.log("global: " + num);
</script>

在这里插入图片描述
当前作用域没找到的话, 就会往上找

这个语法设定和Java中的变量捕获有点类似


对象

JS 不是面向对象的编程语言, 但是存在对象的概念, 这就意味着 JS 中关于对象的设定和 Java 差别很大
JS 中没有封装, 继承, 多态, 甚至没有类
JS 中没有类, 所有对象类型都是Object

使用 字面量 创建对象 [常用]

<script>
			let student = {
            name: '蔡徐坤',
            age: 25,
            height: 180,
            weight: 70,
            sing: function() {
                console.log("鸡你太美");
            },
            dance: function() {
                console.log('铁山靠');
            },
        };
        console.log(student.age);
        console.log(student.height);
    	student.sing();
        student.dance();
</script>

在这里插入图片描述

使用 new Object 创建对象

<script>
		let student = new Object();
        student.name = "蔡徐坤";
        student.height = 180;
        student.age = 25;
        student.sing = function() {
            console.log("鸡你太美");
        }
        student.dance = function() {
            console.log('铁山靠');
        }
        console.log(student.age);
        console.log(student.height);
        student.sing();
        student.dance();
</script>

在这里插入图片描述
JS 中的对象里面有啥属性, 有啥方法, 都不是提前约定好的, 而是随时可以添加.