1. 初识Js
1.1 浏览器执行JS
浏览器分成两部分:渲染引擎和JS引擎
渲染引擎:用来解析HTML和CSS,俗称内核,比如Chrome浏览器的blink,老版本的webkit。
JS引擎:也称为JS解释器。用来读取网页中的JS代码,对其处理后运行,比如Chrome浏览器的V8。
注 浏览器本身不会执行JS代码,而是通过JS引擎执行JS代码。JS引擎执行代码时逐行解释每一句源码,转换为机器语言然后由计算机去执行,所以JS归为脚本语言,会逐行解释执行。
1.2 JS的组成
- JS由三部分组成:
- ECMAScript:Javascript语法
- DOM:页面文档对象模型
- BOM:浏览器对象模型
ECMAScript规定了JS的编程语法和基础知识核心,是所有浏览器厂商共同遵守的一套JS语法工业标准
DOM(Document Object Model)——文档对象模型,是W3C组织推荐的处理可扩展标记语言的标准编程接口,通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色...)
BOM(Browser Object Model)——浏览器对象模型,提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过DOM可以操作浏览器窗口(弹出框、控制浏览器跳转、获取分辨率)
1.3 JS三种书写位置
| 行内式 | 内嵌式 | 外部 |
|---|---|---|
| 在HTML中推荐使用双引号,JS中推荐使用单引号。 | 可以将多行JS代码写到script标签中。 | 引用外部JS文件的script标签中间不可以写代码。 |
| 特殊情况下使用 | 是JS学习时常用的方式 | 适用于JS代码量大的情况 |
1.4 JS注释与输入输出语句
JS注释
| 单行注释 | 多行注释 |
|---|---|
| // | /**/ |
| ctrl+/ | ctrl+shift+/ |
JS输入输出语句
| 方法 | 说明 | 归属 |
|---|---|---|
| alert(msg) | 浏览器弹出警示框 | 浏览器 |
| console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 |
| prompt(info) | 浏览器弹出输入框,用户可以输入,取过来的值时字符型的 | 浏览器 |
1.5 解释型语言和编译型语言
- 程序语言翻译成机器语言的工具叫翻译器。
- 翻译器翻译的方式有两种:编译和解释,区别在于翻译的时间点不同。
- 编译器是在代码执行之前进行编译,生成中间代码。
- 解释器是在运行时进行及时解释,并立即执行。
1.6 标识符、关键字、保留字
- 标识符:开发者为变量、属性、函数、参数取的名字。标识符不能是关键字或保留字。
- 关键字:JS本身已经使用了的字,不能再用它们充当变量名、方法名。
break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with - 保留字:预留的“关键字”,不能使用它们当变量名。
boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、implements、import、int、interface、long、mative、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile
2. JS变量
2.1 变量概述与使用
通俗:变量是用于存放数据的容器,我们通过变量名获取数据,甚至数据可以修改。
变量的本质:变量是程序在内存中申请的一块用来存放数据的空间。
简单案例:变量的使用
1.弹出一个输入框,提示用户输入姓名,
2.弹出一个对话框,输出用户刚才输入的姓名。
<script>
var name=prompt('请输入您的姓名');
alert(name);
<script/>
2.2 变量语法扩展
更新变量:一个变量被重新赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。
声明多个变量:
var age=18,
address='Beijing',
gz=2000;
声明变量的多个情况:
//1. 只声明 不赋值
var sex;
console.log(sex);//undefined
//2. 不声明 不赋值 直接使用
console.log(tel);//error: tel is not defined
//3.不声明 只赋值
qq=110;
console.log(qq);//110
2.3 变量命名规范
- 由字母、数字、下划线、美元符号($)组成。
- 严格区分大小写。
- 不能以数字开头。
- 不能用关键字(var、for、if...)和保留字。
- 变量名必须有意义。
- 遵守驼峰命名法。首字母小写,后面单词的首字母要大写。
- 尽量不要用name作为变量名称。
2.4 变量交换案例
var temp;
var apple1='青苹果';
var apple2='红苹果';
temp=apple1;
apple1=apple2;
apple2=temp;
2.5 小结
| Q | A |
|---|---|
| 为什么需要变量? | 因为一些数据需要保存,所以需要变量 |
| 变量是什么? | 变量就是一个容器,用来存放数据,方便以后就我们使用数据 |
| 变量的本质是什么? | 变量是内存中的一块空间,用来存储数据 |
| 变量怎么使用? | 声明变量,然后赋值,声明变量的本质是去内存申请空间。 |
| 什么是变量的初始化? | 声明变量并赋值。 |
3. 数据类型
3.1 数据类型简介
为什么需要数据类型
在计算机中,不同数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。
数据类型的可变化性
Javascript是一种弱类型或者说是动态语言,变量的数据类型是可以变化的。Javascript变量数据类型是在程序运行过程中,JS引擎根据=右边的值来确定的。
3.2 数据类型分类
JS把数据类型分为两类:
简单数据类型 (Number, String, Boolean, Undefined, Null, symbol(代表创建后独一无二且不可变的数据类型))又叫做基本数据类型、值类型,其中基本包装类型:Boolean, Number, String。
复杂数据类型 (Object、Array数组、Function)又叫做引用类型,在存储时变量中存储的仅仅是地址(引用)。通过new关键字创建的对象(系统对象、自定义对象)
- 特殊:简单数据类型null返回的是一个空的对象 object。如果有个变量以后打算存储对象,暂时没想好放啥,这个时候就给null。
- 访问一个没有被赋值过的变量(属性),返回的是
undefined。
3.2.1 简单数据类型
| 简单数据类型 | 说明 | 默认值 |
|---|---|---|
| Number | 数字型,包含整型值和浮点型值 | 0 |
| Boolean | 布尔值类型,加法运算:true-1,false-0 | false |
| String | 字符串型,引号可以是'' "" 推荐单引号 | "" |
| Undefined | var a;声明了变量a但是没有给值,此时a=undefined | undefined |
| Null | var a=null; 声明了变量a为空值 | null |
3.2.2 数字型
- 进制:八进制前加0,十六进制前加0x。
- 范围:
Number.MIN_VALUENumber.MAX_VALUE - 三个特殊值:无穷
Infinity``-Infinity非数字NaN - isNaN()判断非数字,并返回一个值。
3.2.3 字符串型
-
引号嵌套:外双内单,外单内双。
-
转义字符:
转义符 解释 \n换行 \\斜杠 \\'单引号 \"双引号 \ttab缩进 \b空格 -
字符串长度:str.length
-
字符串拼接:字符串+任何类型=拼接后的新字符串,通常将字符串和变量来拼接。
var variable=undefined; console.log(variable+'you');//undefinedyou console.log(variable+1);//NaN var sapce=null; console.log(sapce+'you');//nullyou console.log(sapce+1);//1 -
字符串与别的类型相加会转换为字符串,
+也可用于字符串转数字console.log(1 + "1", null + " is not " + undefined);//11 null is not undefined console.log(+'1', +(1 + '1'), +'不是一个数字');//1 11 NaN // NaN: Not-A-Number console.log(typeof NaN);//number NaN表示数字运算出错的结果处理。
3.3 数据类型相关方法和知识点
获取变量的数据类型typeof
var num=10;
console.log(typeof num);//number
var str='s';
console.log(typeof s);//string
var timer=null;
console.log(typeof timer);//object !!!!!!
字面量
表示如何表达这个值
- 数字字面量:8,9,10
- 字符串字面量:'前端'
- 布尔字面量:true, false
数据类型转换
-
转换为字符串
方式 说明 案例 toString var num=1; alert(num.toString()); String()强制转换 var num=1; alert(String(num)); 加号拼接字符串 隐式转换,和字符串拼接的结果都是字符串 var num=1; alert(num+''); -
转换为数字型
方式 说明 案例 parseInt(string) string类型→整数数值 parseInt('78') parseFloat(string) string类型→浮点数数值 parseFloat('34') Number()强制转换 string类型→数值型 Number('12') js隐式转换( - * /)利用算术运算隐式转换为数值型 '12'-0 -
转换为布尔型
Boolean()函数,将其他类型转化成布尔型。
- 代表空、否定的值会被转换为false,如
、0NaNnullundefined - 其余值都会被转化为true。
- 代表空、否定的值会被转换为false,如
4.深入理解简单数据类型和复杂数据类型的区别
4.1 两种数据类型的区别
存放位置不同
- 基本类型的变量会保存在栈内存中,如果在一个函数中声明一个基本类型的变量,这个变量在函数执行结束后会自动销毁。
- 引用类型的变量名会保存在栈内存中,但是变量值会存储在堆内存中,引用类型的变量不会自动销毁,当没有引用变量引用它时,系统的垃圾回收机制会回收它。
深拷贝与浅拷贝 赋值不同
- 基本类型的赋值相当于深拷贝,赋值后相当于又开辟了一个内存空间,如下所示:
let a = 100; let b = a; b = 101; console.log(a, b); // 100 101 a 的值改变时并不影响 b 的值。 - 引用类型的赋值是浅拷贝,当我们对对象进行操作时,其实操作的只是对象的引用,如下所示:
let obj = { name: "你好", }; let obj2 = obj; obj2.name = "你好世界"; console.log(obj.name, obj2.name); //你好世界 你好世界,把 obj 的值赋值给 obj2,当 obj2 的值改变时,obj 的值也被改变。
4.2 实现一个对象的深拷贝
JSON.stringify 和 JSON.parse API
let obj = {
name: "你好",
};
let obj2 = JSON.parse(JSON.stringify(obj));
obj2.name = "你好世界";
console.log(obj.name, obj2.name); // 你好 你好世界
- JSON.stringify() : 将 JavaScript 值转换为 JSON 字符串;
- JSON.parse() :将 JSON 字符串转化为 JavaScript 对象
- 缺点:当
obj里面有函数或undefined就会失效。let obj = { fn: function () { console.log("你好世界"); }, name: undefined, }; let obj2 = JSON.parse(JSON.stringify(obj)); console.log(obj2); //{}空对象
递归
递归遍历对象的每个属性,分别赋值到一个新对象去。
function deep(obj) {
let oo = {};
for (const key in obj) {
if (typeof obj[key] === "object") {
oo[key] = deep(obj[key]);
} else {
oo[key] = obj[key];
}
}
return oo;
}
4.3 堆和栈
堆栈空间分配区别:
- 栈(操作系统):由OS自动分配释放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存到栈里。
- 堆(操作系统):存储复杂数据类型(对象),一般由程序员分配释放,若程序员不释放则由垃圾回收机制回收;复杂数据类型存到堆里。
- 注:堆栈是抽象概念。JS里没有堆栈的概念,通过堆栈的方式,更容易理解代码的执行方式。
利用堆栈理解:简单数据类型的传参
- 函数的形参可以看做一个变量,把一个值类型变量传给函数的形参,相当于把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量。
利用堆栈理解:复杂数据类型的传参
-
当我们把引用类型变量传递给形参时,其实是把变量在栈空间里保存的堆地址赋值给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
function Person (name) { this.name = name; } function f1(x) {//x=P console.log(x.name); // 2.刘德华 x.name =“张学友”; console.log (x.name);// 3.张学友 } var p = new Person("刘德华"); console.log (p.name); // 1. 刘德华 f1(p); console. log (p.name);// 4. 张学友