Javascript基础

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
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 引入外部的 js 文件 -->
<script src="tool.js"></script>
</body>
</html>

上面这段代码,依然是放到body标签里,可以和内嵌的js代码并列。另外,引用外部 JS文件的 script 标签中间不可以再写代码。

Javascript语法

语法总览

  1. JavaScript对换行、缩进、空格不敏感。每一条语句以分号结尾。

  2. 所有的符号,都是英语的。比如括号、引号、分号。

  3. 严格区分大小写。

  4. 注释

HTML、CSS、JavaScript三者的注释格式。

  • HTML 的注释
1
<!-- 我是注释  -->
  • CSS的注释
1
2
3
4
5
6
<style type="text/css">
/*
我是注释
*/

</style>

注意:CSS只有/* */这种注释,没有//这种注释。而且注释要写在<style>标签里面才行。

  • JavaScript 的注释

单行注释:

1
// 我是注释

多行注释:

1
2
3
4
/*
多行注释1
多行注释2
*/

输入输出

alert("")语句,弹出“警告框”。

console.log("")表示在控制台中输出

prompt()就是专门用来弹出能够让用户输入的对话框。用得少,测试的时候偶尔会用。

字面量

包括数字、字符串、布尔值。“字面量”即常量,是固定值,不可改变。看见什么,它就是什么。

1
2
3
4
5
alert(369)
console.log('886');
if (true) {

}

一般不直接使用,还是用变量好。

变量

在ES6语法之前,统一使用var关键字来声明一个变量。比如:

1
var name; // 声明一个名为 name 的变量

在ES6语法及之后,可以使用 constlet关键字来声明一个变量

1
2
3
const name; // 定义一个常量

let age;

如果你想定义一个常量,就用 const;如果你想定义一个变量,就用 let。

变量的声明和赋值,写在一起就行。复赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。

声明多个变量时,只需要写一个 var, 多个变量名之间用英文逗号隔开。

为什么用 let ?

变量升级问题。


标识符:在JS中所有的可以由我们自主命名的都可以称之为标识符。

例如:变量名、函数名、属性名、参数名都是属于标识符。通俗来讲,标识符就是我们写代码时为它们起的名字。

关键字:是指 JS 本身已经使用了的单词,我们不能再用它们充当变量、函数名等标识符。

JS 中的关键字如下:

关键字 >folded
1
2
3
4
5
6
7
8
9
10
11
breakcontinuecase、default、

ifelse、switch、forindowhile

try、catch、finally、throw、

var、void、functionreturn、new、

this、typeof、instanceof、delete、with、

truefalse、null、undefined

保留字:实际上就是预留的“关键字”。意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不
能使用它们当充当变量名、函数名等标识符。

JS 中的保留字如下:

保留字 >folded
1
2
3
4
5
6
7
8
9
abstract、boolean、byte、char、class、const、

debugger、double、enum、export、extends、final、float、goto

implements、import、int、interface、long、native、package、

private、protected、public、short、static、super、synchronized、throws、

transient、volatile

数据类型

avaScript 是一种「弱类型语言」,或者说是一种「动态语言」,这意味着不需要提前声明变量的类型,在程序运行过程中,类型会自动被确定。JS 的变量数据类型,是在程序运行的过程中,根据等号右边的值来确定的。而且,变量的数据类型是可以变化的。

JS中一共有六种数据类型

  • 基本数据类型(值类型):String 字符串、Number 数值、Boolean 布尔值、Null 空值、Undefined 未定义。

  • 引用数据类型(引用类型):Object 对象。

内置对象 Function、Array、Date、RegExp、Error等都是属于 Object 类型。也就是说,除了那五种基本数据类型之外,其他的,都称之为 Object类型。

数据类型区别

  • 基本数据类型:参数赋值的时候,传数值。保存在栈内存。

  • 引用数据类型:参数赋值的时候,传地址(修改的同一片内存空间)。保存在堆内存。

字符串

字符串的不可变性

字符串里面的值不可被改变。虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

代码举例:

1
2
3
var str = 'hello';

str = 'bye';

比如上面的代码,当重新给变量 str 赋值时,常量hello不会被修改,依然保存在内存中;str 会改为指向bye

模板字符串(模板字面量)

ES6中引入了模板字符串,让我们省去了字符串拼接的烦恼。

在模板字符串中插入变量

以前,让字符串进行拼接的时候,是这样做的:(传统写法的字符串拼接)

1
2
3
var name = 'smyhvae';
var age = '26';
console.log('name:' + name + ',age:' + age); //传统写法

这种写法,比较繁琐,而且容易出错。

现在,有了 ES6 语法,字符串拼接可以这样写:

1
2
3
4
5
6
var name = 'qianguyihao';
var age = '26';

console.log('我是' + name + ',age:' + age); //传统写法

console.log(`我是${name},age:${age}`); //ES6 写法。注意语法格式

注意,上方代码中,倒数第二行用的符号是单引号,最后一行用的符号是反引号(在 tab 键的上方)。

在模板字符串中插入表达式

以前,在字符串中插入表达式的写法必须是这样的:

1
2
3
const a = 5;
const b = 10;
console.log('this is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');

现在,通过模板字符串,我们可以使用一种更优雅的方式来表示:

1
2
3
4
5
6
const a = 5;
const b = 10;

// 下面这行代码,故意做了换行。
console.log(`this is ${a + b} and
not ${2 * a + b}.`);

打印结果:

1
2
this is 15 and
not 20.

模板字符串中可以换行

因为模板字符串支持换行,所以可以让代码写得非常美观。

代码举例:

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const result = {
name: 'ivy',
age: 18,
sex: '男',
};

// 模板字符串支持换行
const html = `<div>
<span>${result.name}</span>
<span>${result.age}</span>
<span>${result.sex}</span>
</div>`;

console.log(html); // 打印结果也会换行

模板字符串中可以调用函数

模板字符串中可以调用函数。字符串中调用函数的位置,将会显示函数执行后的返回值。

举例:

1
2
3
4
5
function getName() {
return 'ivy';
}

console.log(`www.${getName()}.com`); // 打印结果:www.ivy.com

模板字符串支持嵌套使用

1
2
3
4
5
6
7
8
9
10
11
const nameList = ['ivy1', 'ivy2', 'ivy3'];

function myTemplate() {
// join('') 的意思是,把数组里的内容合并成一个字符串
return `<ul>
${nameList
.map((item) => `<li>${item}</li>`)
.join('')}
</ul>`;
}
document.body.innerHTML = myTemplate()

数组

数值

在JS中所有的数值都是 Number 类型,包括整数和浮点数。

NaN:是一个特殊的数字,表示Not a Number,非数值。比如:

1
2
3
console.log("abc" / 18);  //结果是NaN

console.log("abc" * "abcd"); //按理说,字符串相乘是没有结果的,但如果你非要让JS去算,它就一定会给你一个结果。结果是NaN

注意:typeof NaN的返回结果是 number。

Undefined和任何数值计算的结果为 NaN。NaN 与任何值都不相等,包括 NaN 本身。

连字符和加号的区别

键盘上的+可能是连字符,也可能是数字的加号。如下:

1
2
3
console.log("我" + "爱" + "你");	//连字符,把三个独立的汉字,连接在一起了
console.log("我+爱+你"); //原样输出
console.log(1+2+3); //输出6

输出:

1
2
3
我爱你
我+爱+你
6

总结:如果加号两边都是 Number 类型,此时是数字相加。否则,就是连字符(用来连接字符串)。

举例1:

1
2
3
var a = "1";
var b = 2;
console.log(a + b);

控制台输出:

1
12

举例2:

1
2
3
var a = 1;
var b = 2;
console.log("a" + b); //"a"就不是变量了!所以就是"a"+2 输出a2

控制台输出:

1
a2

在变量中加入字符串进行拼接,可以被同化为字符串。

隐式转换

我们知道,"2"+1得到的结果其实是字符串,但是"2"-1得到的结果却是数值1,这是因为计算机自动帮我们进行了“隐式转换”。

也就是说,-*/%这几个符号会自动进行隐式转换。例如:

1
2
var a = "4" + 3 - 6;
console.log(a);

输出结果:

1
37

虽然程序可以对-*/、`%``这几个符号自动进行“隐式转换”;但作为程序员,我们最好自己完成转换,方便程序的可读性。

例:

1
2
3
4
5
6
7
				  //a         b
var a = "1";
var b = 2;
a = b + a; //"21" 2
b = b + a; //"21" "221"
console.log(a); //21
console.log(b) //221

效果:

1
2
21
221

例:

1
2
3
var a = "3";
var b = 2;
console.log(a-b);

效果:(注意,字符串 - 数值 = 数值)

1
1

Null

null 专门用来定义一个空对象(例如:let a = null)。

如果你想定义一个变量用来保存引用类型,但是还没想好放什么内容,这个时候,可以在初始化时将其设置为 null。

比如:

1
2
let myObj = null;
cosole.log(typeof myObj); // 打印结果:object

补充:

  • Null 类型的值只有一个,就是 null。比如 let a = null

  • 使用 typeof 检查一个 null 值时,会返回 object。

undefined

case1:变量已声明,未赋值时

声明了一个变量,但没有赋值,此时它的值就是 undefined。举例:

1
2
3
let name;
console.log(name); // 打印结果:undefined
console.log(typeof name); // 打印结果:undefined

补充:

  • Undefined 类型的值只有一个,就是 undefind。比如 let a = undefined

  • 使用 typeof 检查一个 undefined 值时,会返回 undefined。

case2:变量未声明(未定义)时

如果你从未声明一个变量,就去使用它,则会报错(这个大家都知道);此时,如果用 typeof 检查这个变量时,会返回 undefined。举例:

1
2
console.log(typeof a); // undefined
console.log(a); // 打印结果:Uncaught ReferenceError: a is not defined

case3:函数无返回值时

如果一个函数没有返回值,那么,这个函数的返回值就是 undefined。

或者,也可以这样理解:在定义一个函数时,如果末尾没有 return 语句,那么,其实就是 return undefined

举例:

1
2
3
function foo() {}

console.log(foo()); // 打印结果:undefined

case4:调用函数时,未传参

调用函数时,如果没有传参,那么,这个参数的值就是 undefined。

举例:

1
2
3
4
5
function foo(name) {
console.log(name);
}

foo(); // 调用函数时,未传参。执行函数后的打印结果:undefined

实际开发中,如果调用函数时没有传参,我们可以给形参设置一个默认值:

1
2
3
4
5
function foo(name) {
name = name || 'qianguyihao';
}

foo();

ES6 之后,上方代码也可以这样写:

1
2
3
function foo(name = 'qianguyihao') {}

foo();

null 和 undefined 有很大的相似性。看看 null == undefined 的结果为 true 也更加能说明这点。

但是 null === undefined 的结果是 false。它们虽然相似,但还是有区别的,其中一个区别是,和数字运算时:

  • 10 + null 结果为 10。

  • 10 + undefined 结果为 NaN。

规律总结:

  • 任何数据类型和 undefined 运算都是 NaN;

  • 任何值和 null 运算,null 可看做 0 运算。

数据类型转换

运算符

比较算符===,!==等。逻辑算符&&,||,!等。

控制语句

ifswitchwhilefor。懂的都懂,典中典了。

函数与方法

函数是对象方法的一部分,不过不重要,会用就行。

函数使用function functionName(){}定义,使用functionName()调用。匿名函数无函数名,一般与事件处理程序一并使用,或分配到变量,使用varName()调用,但这样不如直接命名一个函数,所以这并不常见。

事件

对于事件处理器,可以使用匿名函数、有名字的函数赋值到事件处理参数和DOM,如下:

  • btn.onclick = function(){}
  • function eventReact(){} btn.onclick = eventReact()
  • btn.addEventListener('click',eventReact)

其中DOM的事件处理函数需要两个参数,事件名称和处理函数,当然,同第一项写成匿名函数也可以

btn.addEventListener('click', function(){})

DOM的方式可以清除废弃的事件处理器,给监听器注册多个处理器等。

事件的冒泡与捕获

这是两个顺序相反的过程,事件捕获时,自祖先元素开始查找。冒泡时,自子元素开始向上,处理事件事,在冒泡阶段注册程序,如果不阻止冒泡链的扩大,则会在所有的父元素同事件执行。但也可以利用冒泡,将重复的子元素事件响应委托到一个父元素中。

作者

ivy

发布于

2019-10-10

更新于

2023-03-25

许可协议

CC BY-NC-SA 4.0

评论