Bootstrap

JavaScript基础语法

 

目录

1.初识JavaScript

1.1背景知识

1.2JS的三种书写方式

行内式

内嵌式

外部式

2.语法简介

2.1变量的使用

变量创建方法

动态类型

2.2基本数据类型 

2.3数组

js数组创建方式

遍历方式

添加元素:尾插

​编辑删除元素:splice

2.4函数

格式

函数表达式

作用域

2.5对象

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

使用 new Object 创建对象

使用 构造函数 创建对象 

new关键字的理解


1.初识JavaScript

1.1背景知识

JavaScript简称js,是世界上最流行的编程语言之一.

是一个脚本语言, 通过解释器运行

主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行

JS和html和css的关系

html: 网页的结构

css:网页的表皮

JS:网页的灵魂

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

它和Java编程语言还是有不少关系的,比如在chrome里专门有一个模块.JS引擎,就相当于JVM能识别并运行.class文件一样,能够解释执行JS代码.后来这部分代码被独立出来,封装成独立的程序了(V8引擎),此时JS的适用范围广了.

JS代码具体是如何运行的呢?

程序员编写的代码是保存在文件中的,存储在硬盘上,双击.html文件浏览器就会读取文件,把文件内容加载到内存中,浏览器会解析代码,翻译成二进制让计算机识别(解释器的工作),得到的二进制指令会被CPU加载并执行

这一系列的加载翻译执行的过程都是由浏览器执行的

浏览器分为渲染引擎+JS引擎

渲染引擎:解析html+css,俗称为"内核" 

JS引擎:也就是JS解释器.典型的就是V8引擎

JavaScript的组成

ECMAScript(简称 ES): JavaScript 语法

DOM: 页面文档对象模型, 对页面中的元素进行操作

BOM: 浏览器对象模型, 对浏览器窗口进行操作

我们主要学习前ES,还有DOM的常用API

 我们尝试写第一个JS程序

<body>
    <script>
    alert("你好!");
    </script>
</body>

JavaScript 代码可以嵌入到 HTML 的 script 标签中

1.2JS的三种书写方式

行内式

直接嵌入到html元素内部

 <input type="button" value="点击" onclick="alert('hello!')">

注意:JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示. HTML 中推荐使用双引号, JS 中推荐使用单引号. 

内嵌式

写到script标签中

<body>
    <script>
    alert("你好!");
    </script>
</body>

外部式

写到单独的.js文件中

 引入.js文件

 执行

注意:

script 标签中间不能写代码. 必须空着(写了代码也不会执行).外部式适合代码多的情况

alert能够弹窗,从而让用户看到程序的输出,但是也有不好的地方,有些对话框一弹出来,就会阻止界面的其他部分,也操作不了页面的其它部分,叫做模态对话框

JS中的console.log就可以在控制台进行打印日志,类似于Java中的println一样,也是一种有用的调试手段

 

 输入输出

alert:弹出一个对话框输出结果

prompt:弹出一个输入框输入

还有,html,css,js的注释方式是不相同的

html:<!-- 注释内容 -->

css:/*注释内容*/

js://  注释内容   /*注释内容*/

2.语法简介

2.1变量的使用

js定义变量不用写类型,但是不意味着没有类型,而是变量的类型是通过初始化操作的值来确定的

变量创建方法

var 变量名 = 值;

var 是 JS 中的关键字, 表示这是一个变量.

= 在 JS 中表示 "赋值", 相当于把数据放到内存的盒子中.

= 两侧建议有一个空格 每个语句最后带有一个 ;

初始化的值如果是字符串, 那么就要使用单引号或者双引号引起来

变量定义还可以写 let 变量名 = 值;

var属于老式的写法,let是新式写法

看一个例子: 

<body>
    <script>
        var name = prompt("姓名:");
        var age = prompt("年龄:");
        var score = prompt("分数");
        alert("姓名是:"+ name + "\n" + "年龄是:" + age + "\n" + "分数是:" + score + "\n" );
    </script>
</body>

+ 表示字符串拼接, 也就是把两个字符串首尾相接变成一个字符串.

\n 表示换行

动态类型

JS是动态类型语言,一个变量在程序中,类型可以发生改变,就是动态类型语言(JS,python,PHP...)

运行过程中变量不能发生类型改变就是静态类型(C,java,C++,GO...)

动态类型的特点

1.js的变量类型是程序运行过程中才确定的,运行到=才会确定类型

2.随着程序运行,变量类型可能会发生改变

2.2基本数据类型 

js中内置的几种基本数据类型:

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

Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.

-Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.

NaN: 表示当前的结果不是一个数字.(not a number)

boolean: true 真, false 假.

Boolean 参与运算时当做 1 和 0 来看待

string: 字符串类型.字符串字面值需要使用引号引起来,单引号双引号均可

如果字符串中本来就有引号怎么办?

有些字符不方便输入,就需要用到转义字符

\n :换行

\\ : \

\' : '

\" : "

\t : 空格

undefined: 只有唯一的值 undefined. 表示未定义的值.

null: 只有唯一的值 null. 表示空值.

注意:

null 和 undefined 都表示取值非法的情况, 但是侧重点不同.

null 表示当前的值为空. (相当于有一个空的盒子)  undefined 则表示当前的变量未定义. (相当于连盒子都没有)

js中的运算符和Java中的大多比较类似

== 比较相等(会进行隐式类型转换)

 

此处出发了隐式类型转换,js中针对不同的类型进行比较/运算,会尝试将不同的转换成相同的类型 

 

这里将true转换成了1

=== 比较相等(不会进行隐式类型转换)

像Java这种不太支持隐式类型转换的语言称为强类型语言

JS这种支持隐式类型转换的语言称为弱类型语言

我们看一下各种语言的分类

C++由于要和C兼容,因为C支持隐式类型转换,所以C++也得支持,业界的共识是强类型比弱类型好,类型强说明类型间的区分度就高.编译器能做的检查工作就多,代码就不容易出错 

2.3数组

js数组创建方式

1.使用 new 关键字创建

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

        let arr = new Array();

        let arr2 = [];

        let arr3 = [1,'hello',true,[]];

 js数组中元素类型不要求统一,可以是任意类型,不仅仅js如此,动态类型的语言都是如此.那么底层是如何做到存储这些不同的类型的变量呢?

站在c语言的视角,每个js变量都有一个地址(唯一的身份标识),数组存储的其实是对应的身份标识,身份标识是统一格式的内容,在底层用一个c的数组来存储这些身份标识,在js层面就相当于保存了不同类型的变量

操作数组:访问下标

        let arr = ['微机原理','Javaee','程序设计基础'];
        console.log(arr[0]);
        console.log(arr[1]);
        console.log(arr[2]);
        console.log(arr);

控制台打印:

如果我们打印arr[100]是什么效果?

        console.log('-------------------');
        console.log(arr[100]);

显示未定义.此时我们给100赋值

 

我们可以看到.赋值成功了,中间empty x 97代表着中间还有97个位置是空的

我们再来看个奇怪的下标

看到这里,你会发现,js的数组不是传统的数组了(只能按照下标取元素).它是带有键值对性质的数组

就像是Map+数组,很多动态类型的语言都是如此,,不过python数组没有这么灵活.在计算机中灵活就意味着容易出错,因此js的更高版本引入了专门的map来表示键值对.

遍历方式

        //1.
        for (let i = 0;i<arr.length;i++){
            console.log(arr[i]);
        }
        //2.
        for(let i in arr){
            //此处的i是数组下标
            console.log(arr[i]);
        }
        //3.
        for(let elem of arr){
            //此处elem是数组元素
            console.log(elem);
        }

添加元素:尾插

删除元素:splice

这个方法相当于一个万能方法,可以用来插入,修改,删除....

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

函数意思是:将变长参数的内容,替换到前面指定的区间,从start开始替换count个

如果后面没有变长参数,就相当于删除操作

如果变长参数和前面指定的区间个数一样,那就是替换

如果变长参数比前面区间个数长,就是新增元素

 删除:

 

 新增:

替换:

2.4函数

格式

创建函数/函数声明/函数定义

function 函数名(形参列表) {    

函数体    

return 返回值;

函数调用

函数名(实参列表)           // 不考虑返回值

返回值 = 函数名(实参列表)   // 考虑返回值

我们先来写一个函数

        function add(x,y){
            return x+y;
        }

开头有函数关键字,function,函数名add,形参列表(x,y).

我们看到,形参列表参数没有类型,也就是什么类型的都可以,只要传入的变量能够在函数内部正常工作即可

也没有返回值类型,像java中的public static.....都没有

另外,函数形参和实参的个数可以不匹配,但是实际开发要求匹配.当实参和形参个数不匹配的时候,是不会报错的,会尽可能去执行

如果实参个数比形参个数多,那么多出来的不参与函数运算

我们可以看到,并没有将30进行运算

 

如果实参个数比形参个数少, 则此时多出来的形参值为 undefined

 

NaN:not a number 

对于js这样的动态类型语言,是不需要重载这样的语法的,我们看下面这个函数

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

        console.log(add(10));
        console.log(add(10,20));
        console.log(add(10,20,30));
        console.log(add(10,20,30,40));

 

函数表达式

指把一个匿名函数赋值给一个变量,然后就可以通过这个变量来调用函数了.

js中可以像普通变量一样,将函数赋值给一个变量,同时也可以将函数作为另一个函数的参数,或者把函数做为另一个函数的返回值,java是做不到的,这个特性称为"一等公民"

还是相同的结果,add变量的类型,就叫做function类型,对于function类型的变量是可以调用的

 

作用域

指某个标识符名字在代码中的有效范围.

全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.

局部作用域/函数作用域: 在函数内部生效.

看个例子:

        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('golbal: '+ num);
        </script>

js会先找当前作用域,如果当前没有,就会往上层作用域找,一直往上层直到全局作用域(从内到外依次进行查找)如果还没找到就会报错/undefined ,这个语法类似于java中的变量捕获

2.5对象

js不是面向对象语言,但是存在对象的概念,所以这里的对象和jjava中的对象差异是很大的

在 JS 中, 字符串, 数值, 数组, 函数都是对象.

每个对象中包含若干的属性和方法. 属性: 事物的特征. 方法: 事物的行为

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

        let a = {}; // 创建了一个空的对象

        let b = {
            name:'zhangsan',
            age:18,
            scoer:59,
            sayHello: function() {
                console.log("hello");
            }
        };

使用 { } 创建对象

属性和方法使用键值对的形式来组织

键值对之间使用 , 分割.最后一个属性后面的 , 可有可无

键和值之间使用 : 分割

方法的值是一个匿名函数

 使用对象的属性和方法

使用 new Object 创建对象

        let b = new Object();

        b.name = 'zhangsan';
        b.age = 18;
        b['score'] = 90;
        b.sayHello = function () {
         console.log("hello");
        }

        // 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
        console.log(b.name);
        // 2. 使用 [ ] 访问属性, 此时属性需要加上引号
        console.log(b['score']);
        // 3. 调用方法, 别忘记加上 ()
        b.sayHello();
        

注意

使用 { } 创建的对象也可以随时使用 b.name = "zhangsan"; 这样的方式来新增属性

使用 构造函数 创建对象 

前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便 的创建 多个对象

使用构造函数可以把相同的属性和方法的创建提取出来, 简化开发过程.

基本语法

function 构造函数名(形参) {
    this.属性 = 值;
    this.方法 = function...
}
    
var obj = new 构造函数名(实参);

注意:

this 关键字来表示当前正在构建的对象.

构造函数的函数名首字母一般是大写的.

构造函数的函数名可以是名词.

构造函数不需要 return

创建对象的时候必须使用 new 关键字

 看一个例子

        function Dog(name, type, sound) {
            this.name = name;
            this.type = type;
            this.wang = function () {
                console.log(sound); // 别忘了作用域的链式访问规则
            }        
        }
        let dabai = new Dog('dabai','柴犬','汪');
        let erbai = new Dog('erbai','哈士奇','汪汪汪');

        console.log(dabai);
        dabai.wang();

new关键字的理解

new 的执行过程: 先在内存中创建一个空的对象, this 指向刚才创建的空对象(将上一步的对象作为 this 的上下文) ,然后 执行构造函数的代码, 给对象创建属性和方法 ,最后 返回这个对象 (构造函数本身不需要 return, 由 new 代劳了)

;