一、初识JS
1、浏览器与JS
浏览器分为两部分:渲染引擎和JS引擎
- 渲染引擎:用来解析HTML和CSS,俗称内核,比如Chrome的blink,老版本的webkit
- JS引擎(解释器):用来读取网页中JavaScript代码,对其逐行解释为机器语言后运行,比如Chrome的V8
2、JS的组成
- ECMAScript:
JavaScript和Jscript语法是其实现和拓展,ECMAScript规定了JS的编程语法和核心知识,是所有浏览器产商共同遵守的一套JS语法工业标准 - DOM:页面文档对象模型,是
W3C组织推荐的处理可拓展标记语言的标准编程接口,通过DOM提供的接口可以对页面上的各种元素进行操作 - BOM:浏览器对象模型,它提供了独立于内容的、可与浏览器窗口进行互动的对象结构,通过BOM可以操作浏览器窗口
3、书写位置
有行内、内嵌、外部三种方式
// 行内
<input type="button" onclick="alert('Hello')"/>
// 内嵌
<script>
alert('Hello')
</script>
// 外部
<script src="my.js"></script>
4、输入输出
- alert(msg):浏览器弹出警示框,归属浏览器
- console.log(msg):浏览器控制台输出信息,归属浏览器
- prompt(info):浏览器弹出输入框,归属浏览器
5、变量
// 声明
var age;
// 赋值
age = 18;
// 直接初始化
var myname = "zhangsan"
// 只声明不赋值,为 undefined
var sex;
console.log(sex);
// undefined
- 由字母、数字、下划线、美元符号构成
- 严格区分大小写
- 不能以数字开头
- 不能是关键字、保留字
- 遵循驼峰命名法
- 变量名要有意义
- 尽量不要使用name作为变量名(未声明就输出时不报错)
6、数据类型
① 基本数据类型
| 基本数据类型 | 说明 | 默认值 |
|---|---|---|
| Number | 数字型,包含整型和浮点型 | 0 |
| Boolean | 布尔值 | false |
| String | 字符串型,都带引号"" | "" |
| Undefined | var a;,声明了但没有赋值 | undefined |
| Null | var a = null;,声明了是空值 | null |
-
在数字前面加
0表示八进制,加0x表示十六进制var num = 010; console.log(num); // 8 var num2 = 0xa; console.log(num2); // 10 -
数值的最大值和最小值:
Number.MAX_VALUE、Number.MIN_VALUE -
无穷大和无穷小:
Infinity、-Infinity -
非数字:
NaN -
isNaN:判断是否是非数字 -
布尔值和数字相加时,true值为1,false值为0
-
// 一个声明后没有被赋值的变量会有一个默认值 undefined (相连或者相加时注意结果) var variable; console.log(variable); // undefined console.log('你好' + variable); // 你好undefined console.log(11 + variable); // NaN console.log(true + variable); //NaN // 一个声明变量给 null 值,里面存的值为空 var vari = null; console.log('你好' + vari); // 你好null console.log(11 + vari); // 11 console.log(true + vari); // 1
② 转义字符
| 转义符 | 含义 |
|---|---|
\n | 换行符,即newline |
\ | 斜杠`` |
' | '单引号 |
" | "双引号 |
\t | 缩进,即tab |
\b | 空格,即blank |
③ 字符串转换
- toString:转换成字符串,
num.toString(); - String:强制转换成字符串,
String(num); +拼接:和字符串拼接的结果都是字符串,num + ' '
- parseInt(String):字符串转换成整型
- parseFloat(String):字符串转换成浮点型
- Number():强制转换数值型
-
Boolean():其他值转换为布尔值
-
代表空、否定的值会被转换为false ,
''、0、NaN、null、undefined -
其余值都会被转换为true
console.log(Boolean('')); // false console.log(Boolean(0)); // false console.log(Boolean(NaN)); // false console.log(Boolean(null)); // false console.log(Boolean(undefined)); // false console.log(Boolean('小白')); // true console.log(Boolean(12)); // true
7、解释语言和编译原因
翻译器翻译的方式有两种: 一个是编译,另外一个是解释。两种方式之间的区别在于翻译的时间点不同:
- 编译器是在代码执行之前进行编译,生成中间代码文件。
- 解释器是在运行时进行及时解释,并立即执行(当编译器以解释方式运行的时候,也称之为解释器)。
8、标识符、关键字、保留字
- 标识(zhi)符,是指开发人员为变量、属性、函数、参数取的名字。标识符不能是关键字或保留字。
- 关键字,是指
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等。
9、其他
① arguments
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。
所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
function fn() {
console.log(arguments); // 里面存储了所有传递过来的实参
}
fn(1, 2, 3);
// 伪数组并不是真正意义上的数组
// 具有数组的length属性
// 按照索引的方式进行存储
// 但没有真正数组的一些方法pop()、push()等等
② JS没有块级作用域
// java
if(xx) {
int num = 10;
}
System.out.print(num); // 不能调用num
// JS
if(xx) {
var num = 10;
}
console.log(num); // 可以调用num
实际在es6才新增了块级作用域
③ 预解析
js引擎运行js分为两步:
1、预解析:js引擎会把js里面所有的var还有function提升到当前作用域的最前面
2、代码执行:按照代码书写的顺序从上往下执行
预解析分为变量预解析(变量提升) 和函数预解析(函数提升)
-
变量提升就是把所有的变量声明提升到当前的作用域最前面,但不提升赋值操作
console.log(num); var num = 10; // undefined // 其实相当于 var num; console.log(num); num = 10; -
函数提升就是把所有的函数声明提升到作用域的最前面,函数表达式调用必须写在表达式下面
fn(); function fn() { console.1og(11); } // 11 fun(); var fun = function() { console.1og(22); } // 报错
④ 创建对象
var obj = {
// 属性、方法等
}
var obj = new Object();
⑤ 构造函数
- 构造函数首字母要大写
- 不需要return即可返回结果
⑥ new关键字执行过程
- 在内存中创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象,所以构造函数里面不需要return
⑦ for in 遍历对象
for(var k in obj){
console.log(k); // 得到属性名
console.log(onj[k]); // 得到属性
}
⑧ 内置对象
JavaScript中的对象分为3种:自定义对象、内置对象、浏览器对象。前面两种对象是JS基础内容,属于ECMAScript; 第三个浏览器对象属于JS独有的
内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能 (属性和方法)
a、Math
Math无需实例化
Math.radom(),返回一个[0,1)的随机数
b、Date
Date对象要实例化才能使用,Date对象是基于1970年1月1日(世界标准时间)起的毫秒数
// 获得Date总的毫秒数(时间戳),不是当前时间的毫秒数,而是距离1970年1月1号过了多少毫秒数
// 通过value0f()、getTime( )
var date = new Date();
console.log(date.valueOf()); //就是现在时间距离1970.1.1总的毫秒数
console.log(date.getTime());
// 最常用的写法
var date1 = +new Date(); // +new Date();返回的就是总的毫秒数
console.log(date1);
// H5新增的,获得总的毫秒数
console.log(Date.now());
// 1664427780640
// 1664427780640
// 1664427780643
// 1664427780643
10、数组
① 创建
// 利用数组字面量
var arr = [1, 2, 3];
console.1og(arr[0]);
// 利用new Array()
var arr1 = newArray(); //创建了一个空的数组
var arr1 = new Array(2); // 这个2表示数组的长度为2,里面有2个空的数组元素
var arr1 = new Array(2, 3); //等价于[2,3] 这样写表示里面有2个数组元素是2和3
console.log(arr1);
② 判断
// instanceof 运算符可以用来检测是否为数组
vararr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
// Array.isArray(参数);
// H5新增的方法,ie9以上版本支持
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));
③ 添加删除元素
④ 数组索引方法
11、基本包装类型
为了方便操作基本数据类型,,JavaScript 还提供了三个特殊的引用类型:String、Number、Boolean
基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法
var str = 'andy';
console.log(str.length);
// 4
// js把基本数据类型包装为复杂数据类型,其执行过程如下:
// 1.生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy') ;
// 2.赋值给声明的字符变量
str = temp;
// 3.销毁临时变量
temp = null;
① 根据字符返回位置
var str = '改革春风吹满地,春天来了';
console.log(str.index0f('春'));
console.log(str.indexOf('春', 3)); // 从索引号是3的位置开始往后查找
// 2
// 8
② 根据位置返回字符
var str = 'andy';
// charAt(index),根据位置返回字符
console.log(str.charAt(3)); // y
// charCodeAt(index),返回相应索引号的字符ASCII值
// 目的:判断用户按下了哪个键
console.log(str.charCodeAt(0)); // 97
// str[index],H5新增,和charAt等效
console.log(str[0]); // a
③ 字符串拼接
// concat('字符串1', '字符串2',....)
var str = 'andy' ;
console.log(str.concat('red'));
// andyred
// substr('截取的起始位置’,'截取几个字符');
var str1 = '改革春风吹满地';
console.log(str1.substr(2, 2));
// 春风
// 替换字符,replace('被替换的字符','替换为的字符')
// 它只会替换第一个字符
var str = "andyandy";
console.log(str.replace('a','b'));
// bndyandy
// 有一个字符串'abcoefoxyozzopp' 要求把里面所有的0替换为*
var str1 = 'abcoefoxyozzopp';
while(str1.index0f('o') !== -1) {
str1 = str1.replace('o', '*');
}
console.log(str1);
// abc*ef*xy*zz*pp
// 字符转换为数组,split('分隔符')
var str2 = 'red, pink, blue';
console.log(str2.split(','));
var str3 = 'red&pink&blue';
console.log(str3.split('&'));
// [
// "red",
// " pink",
// " blue"
// ]
12、内存分配&参数传递
堆栈空间分配区别:
栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。
堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
简单数据类型存放在栈里面,里接开辟一个空间,存放的是值
复杂数据类型首先在栈里面存放地址(十六进制),然后这个地址指向堆里面的数据
函数的形参也可以看做是一个变量
-
当我们把一个值类型变量作为参数传给函数的形参时,实际是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
// 简单数据类型传参 function fn(a) { a++; console.log(a); } var x = 10; fn(x); console.log(x); // 11 // 10 -
当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一一个对象。
// 复杂数据类型传参 function Person(name) { this.name = name; } function f1(x) { console. log(x.name); // 刘德华 x.name = "张学友"; console. log(x.name); // 张学友 } var p = new Person("刘德华"); console.log(p.name); // 刘德华 f1(p); console.log(p.name); // 张学友