Javascript基础
Javascript基础的学习记录。
JS简介
JavaScript基础分为三个部分:
ECMAScript:JavaScript 的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
DOM:Document Object Model(文档对象模型),操作页面上的元素的API。比如让盒子移动、变色、改变大小、轮播图等等。
BOM:Browser Object Model(浏览器对象模型),操作浏览器部分功能的API。通过BOM可以操作浏览器窗口,比如弹框、控制浏览器跳转、获取浏览器分辨率等等。
通俗理解就是:ECMAScript 是 JS 的语法;DOM 和 BOM 浏览器运行环境为 JS提供的API。
引入JS代码
方式大致有三种,行内、嵌入以及外部引入。一般用外部引入。
行内
1 | <input type="button" value="点我点我" onclick="alert('Hello')" /> |
可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),比如放在上面的 onclick
点击事件中。可读性差。容易出错,不好维护。
关于代码中的「引号」,在HTML标签中,我们推荐使用双引号, JS 中我们推荐使用单引号。
嵌入
我们可以在html 页面的 <body>
标签里放入<script type=”text/javascript”></script>
标签对,并在<script>
里书写JavaScript 代码。练习测试的时候可以用一用。
外部引入
编写另外js文件,在HTML中引用。
1 |
|
上面这段代码,依然是放到body标签里,可以和内嵌的js代码并列。另外,引用外部 JS文件的 script 标签中间不可以再写代码。
Javascript语法
语法总览
JavaScript对换行、缩进、空格不敏感。每一条语句以分号结尾。
所有的符号,都是英语的。比如括号、引号、分号。
严格区分大小写。
注释
HTML、CSS、JavaScript三者的注释格式。
- HTML 的注释
1 | <!-- 我是注释 --> |
- CSS的注释
1 | <style type="text/css"> |
注意:CSS只有/* */
这种注释,没有//
这种注释。而且注释要写在<style>
标签里面才行。
- JavaScript 的注释
单行注释:
1 | // 我是注释 |
多行注释:
1 | /* |
输入输出
alert("")
语句,弹出“警告框”。
console.log("")
表示在控制台中输出
prompt()
就是专门用来弹出能够让用户输入的对话框。用得少,测试的时候偶尔会用。
字面量
包括数字、字符串、布尔值。“字面量”即常量,是固定值,不可改变。看见什么,它就是什么。
1 | alert(369) |
一般不直接使用,还是用变量好。
变量
在ES6语法之前,统一使用var
关键字来声明一个变量。比如:
1 | var name; // 声明一个名为 name 的变量 |
在ES6语法及之后,可以使用 const
、let
关键字来声明一个变量
1 | const name; // 定义一个常量 |
如果你想定义一个常量,就用 const;如果你想定义一个变量,就用 let。
变量的声明和赋值,写在一起就行。复赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。
声明多个变量时,只需要写一个 var, 多个变量名之间用英文逗号隔开。
为什么用 let ?
变量升级问题。
标识符:在JS中所有的可以由我们自主命名的都可以称之为标识符。
例如:变量名、函数名、属性名、参数名都是属于标识符。通俗来讲,标识符就是我们写代码时为它们起的名字。
关键字:是指 JS 本身已经使用了的单词,我们不能再用它们充当变量、函数名等标识符。
JS 中的关键字如下:
1 | break、continue、case、default、 |
保留字:实际上就是预留的“关键字”。意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不
能使用它们当充当变量名、函数名等标识符。
JS 中的保留字如下:
1 | abstract、boolean、byte、char、class、const、 |
数据类型
avaScript 是一种「弱类型语言」,或者说是一种「动态语言」,这意味着不需要提前声明变量的类型,在程序运行过程中,类型会自动被确定。JS 的变量数据类型,是在程序运行的过程中,根据等号右边的值来确定的。而且,变量的数据类型是可以变化的。
JS中一共有六种数据类型
基本数据类型(值类型):String 字符串、Number 数值、Boolean 布尔值、Null 空值、Undefined 未定义。
引用数据类型(引用类型):Object 对象。
内置对象 Function、Array、Date、RegExp、Error等都是属于 Object 类型。也就是说,除了那五种基本数据类型之外,其他的,都称之为 Object类型。
数据类型区别:
基本数据类型:参数赋值的时候,传数值。保存在栈内存。
引用数据类型:参数赋值的时候,传地址(修改的同一片内存空间)。保存在堆内存。
字符串
字符串的不可变性
字符串里面的值不可被改变。虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
代码举例:
1 | var str = 'hello'; |
比如上面的代码,当重新给变量 str 赋值时,常量hello
不会被修改,依然保存在内存中;str 会改为指向bye
。
模板字符串(模板字面量)
ES6中引入了模板字符串,让我们省去了字符串拼接的烦恼。
在模板字符串中插入变量
以前,让字符串进行拼接的时候,是这样做的:(传统写法的字符串拼接)
1 | var name = 'smyhvae'; |
这种写法,比较繁琐,而且容易出错。
现在,有了 ES6 语法,字符串拼接可以这样写:
1 | var name = 'qianguyihao'; |
注意,上方代码中,倒数第二行用的符号是单引号,最后一行用的符号是反引号(在 tab 键的上方)。
在模板字符串中插入表达式
以前,在字符串中插入表达式的写法必须是这样的:
1 | const a = 5; |
现在,通过模板字符串,我们可以使用一种更优雅的方式来表示:
1 | const a = 5; |
打印结果:
1 | this is 15 and |
模板字符串中可以换行
因为模板字符串支持换行,所以可以让代码写得非常美观。
代码举例:
1 | const result = { |
模板字符串中可以调用函数
模板字符串中可以调用函数。字符串中调用函数的位置,将会显示函数执行后的返回值。
举例:
1 | function getName() { |
模板字符串支持嵌套使用
1 | const nameList = ['ivy1', 'ivy2', 'ivy3']; |
数组
数值
在JS中所有的数值都是 Number 类型,包括整数和浮点数。
NaN:是一个特殊的数字,表示Not a Number,非数值。比如:
1 | console.log("abc" / 18); //结果是NaN |
注意:typeof NaN
的返回结果是 number。
Undefined和任何数值计算的结果为 NaN。NaN 与任何值都不相等,包括 NaN 本身。
连字符和加号的区别
键盘上的+
可能是连字符,也可能是数字的加号。如下:
1 | console.log("我" + "爱" + "你"); //连字符,把三个独立的汉字,连接在一起了 |
输出:
1 | 我爱你 |
总结:如果加号两边都是 Number 类型,此时是数字相加。否则,就是连字符(用来连接字符串)。
举例1:
1 | var a = "1"; |
控制台输出:
1 | 12 |
举例2:
1 | var a = 1; |
控制台输出:
1 | a2 |
在变量中加入字符串进行拼接,可以被同化为字符串。
隐式转换
我们知道,"2"+1
得到的结果其实是字符串,但是"2"-1
得到的结果却是数值1,这是因为计算机自动帮我们进行了“隐式转换”。
也就是说,-
、*
、/
、%
这几个符号会自动进行隐式转换。例如:
1 | var a = "4" + 3 - 6; |
输出结果:
1 | 37 |
虽然程序可以对-
、*
、/
、`%``这几个符号自动进行“隐式转换”;但作为程序员,我们最好自己完成转换,方便程序的可读性。
例:
1 | //a b |
效果:
1 | 21 |
例:
1 | var a = "3"; |
效果:(注意,字符串 - 数值 = 数值)
1 | 1 |
Null
null 专门用来定义一个空对象(例如:let a = null
)。
如果你想定义一个变量用来保存引用类型,但是还没想好放什么内容,这个时候,可以在初始化时将其设置为 null。
比如:
1 | let myObj = null; |
补充:
Null 类型的值只有一个,就是 null。比如
let a = null
。使用 typeof 检查一个 null 值时,会返回 object。
undefined
case1:变量已声明,未赋值时
声明了一个变量,但没有赋值,此时它的值就是 undefined
。举例:
1 | let name; |
补充:
Undefined 类型的值只有一个,就是 undefind。比如
let a = undefined
。使用 typeof 检查一个 undefined 值时,会返回 undefined。
case2:变量未声明(未定义)时
如果你从未声明一个变量,就去使用它,则会报错(这个大家都知道);此时,如果用 typeof
检查这个变量时,会返回 undefined
。举例:
1 | console.log(typeof a); // undefined |
case3:函数无返回值时
如果一个函数没有返回值,那么,这个函数的返回值就是 undefined。
或者,也可以这样理解:在定义一个函数时,如果末尾没有 return 语句,那么,其实就是 return undefined
。
举例:
1 | function foo() {} |
case4:调用函数时,未传参
调用函数时,如果没有传参,那么,这个参数的值就是 undefined。
举例:
1 | function foo(name) { |
实际开发中,如果调用函数时没有传参,我们可以给形参设置一个默认值:
1 | function foo(name) { |
ES6 之后,上方代码也可以这样写:
1 | function foo(name = 'qianguyihao') {} |
null 和 undefined 有很大的相似性。看看 null == undefined
的结果为 true
也更加能说明这点。
但是 null === undefined
的结果是 false。它们虽然相似,但还是有区别的,其中一个区别是,和数字运算时:
10 + null 结果为 10。
10 + undefined 结果为 NaN。
规律总结:
任何数据类型和 undefined 运算都是 NaN;
任何值和 null 运算,null 可看做 0 运算。
数据类型转换
运算符
比较算符===,!==等。逻辑算符&&,||,!等。
控制语句
if
、switch
、while
、for
。懂的都懂,典中典了。
函数与方法
函数是对象方法的一部分,不过不重要,会用就行。
函数使用function functionName(){}定义,使用functionName()调用。匿名函数无函数名,一般与事件处理程序一并使用,或分配到变量,使用varName()调用,但这样不如直接命名一个函数,所以这并不常见。
事件
对于事件处理器,可以使用匿名函数、有名字的函数赋值到事件处理参数和DOM,如下:
btn.onclick = function(){}
function eventReact(){} btn.onclick = eventReact()
btn.addEventListener('click',eventReact)
其中DOM的事件处理函数需要两个参数,事件名称和处理函数,当然,同第一项写成匿名函数也可以
btn.addEventListener('click', function(){})
DOM的方式可以清除废弃的事件处理器,给监听器注册多个处理器等。
事件的冒泡与捕获
这是两个顺序相反的过程,事件捕获时,自祖先元素开始查找。冒泡时,自子元素开始向上,处理事件事,在冒泡阶段注册程序,如果不阻止冒泡链的扩大,则会在所有的父元素同事件执行。但也可以利用冒泡,将重复的子元素事件响应委托到一个父元素中。