JavaScript介绍
1.为什么要学JavaScript?
-
网页三部分:
HTML:控制网页的 结构
CSS:控制网页的 样式
JavaScript:控制网页的行为
不同于HTML和css,JavaScript是一门编程语言,因此要比HTML和css复杂一些,学习的时间也更长。
-
最初的javascript
-
用于判断客户端的输入(表单校验)
-
-
现在的JavaScript:
现在的JS无所不能
-
异步与服务器交互(AJAX)
-
网页和特效(演示)
-
服务端开发(nodejs)
-
命令行工具开发(nodejs)
-
桌面程序(Electron)
-
app开发(ReatNative)
-
控制硬件--物联网(Ruff)
-
游戏开发(cavans, cocos2d-js)
-
2.什么是JavaScript?
-
概念 : JavaScript 是一种运行在 客户端 的 脚本语言
-
客户端 : 相对服务端而言的 ; 移动客户端 + PC客户端 (浏览器)
-
脚本语言 :
-
编译语言:Java/C/C++/OC/Swift... 运行代码之前,把所有的代码先编译一遍,再运行每一行代码
-
脚本语言:JavaScript/PHP/Python... 运行一行解析一行,不需要提前 把所有的都编译一遍 , 非编译语言
-
3.JavaScript历史
-
开始阶段 :
-
1995年,Netscape(网景)公司的
Brendan Eich(布兰登·艾奇)
(伊利诺伊大学香槟分校),花了10天时间为Netscape Navigator2.0开发了一个位置为LiveScript
的脚本程序,目的是在浏览器中执行预检测程序(表单校验) -
发展阶段:
-
后来Netscape在与Sun合作之后将其改名为JavaScript。目的是为了利用 Java 这个因特网时髦词汇。
-
微软发布了 IE 3.0 并搭载了一个 JavaScript 的克隆版,叫做 JScript(这样命名是为了避免与 Netscape 潜在的许可纠纷)
-
三足鼎立阶段:
-
CEnvi的scriptEase
-
Netscape的JavaScript
-
IE的JScript
-
-
标准化阶段:1997年,ECMA(欧洲计算机制造商协会)邀请了Netscape、Sun、微软、Borland等公司的一些程序员组成了TC39,最终锤炼出来了ECMA-262,该标准定义了一门全新的脚本语言,名为
ECMAScript
。
4.javascript的组成 (记忆)
-
ECMAScript - JavaScript的核心,ECMAScript是一套标准,规范了语言的基本语法和数据类型,定义了一种语言的标准,与具体实现无关
-
DOM:(Document Object Model)一套操作网页元素的API (方法)
-
BOM:(Browser Object Model)一套操作浏览器功能的API
JavaScript入门
1.JavaScript书写位置
-
第一种 : 写在
script
标签中
<script>
alert('Hello World!');
</script>
-
第二种 : 引入一个js文件
<script src="main.js"></script>
注意:
-
script 可以放在很多地方,,但是我们一般规范些在body里面,放在 html 下面;. .使用src 引入的标签 不能再在标签内写js代码里 (一个标签里面只能有一份js代码)
2.注释
注释代码不会被执行,仅仅起到一个提示的作用。注释可以对复杂的代码进行解释,方便后期的维护和开发。
-
单行注释 :
// 这是单行注释, 单行注释只能写一行代码 // 快捷键: ctrl + /
-
多行注释 :
/* 这是多行注释,在多行注释中可以 换行 sublime Text : 快捷键 ctrl + shift + / vscode : 选中多行直接注释,即可,但是这种多行注释 如果需要得自己手写 */ 在vscode中比较特殊一般情况下,不会出现多行注释,,显示出来的是多个单行注释
-
在写代码的时候,需要写注释,这是一个良好的习惯,
-
大家初学,一定多写注释 ! 把理解的知识再写一遍,效果会更好!!
3.输出语句 (5种)
-
alert : 警告框
//alert会弹出一个警告框 alert("hello world");
-
confirm : 确认框
//confirm弹出一个确定框 confirm("怎么样");
-
prompt : 输入框
//prompt:弹出一个输入框,可以输入值 prompt("请输入你的真是年龄");
-
document.write : 网页中写入内容
//可以识别标签 document.write("hello world"); document.write("<h1>hello world</h1>");
-
控制台输出
//F12打开控制台,在console中可以看到打印的信息 console.log("hello word");
变量
变量 : 可以变化的量
变量的作用 : 存储数据
声明 : 用 var(哇) 来声明
1.变量使用的几种形式
-
直接声明变量
// var 来声明变量的 // age : 变量名 // 结构 : var + 变量名 ; var age; console.log // undefined 只声明没有赋值
-
先声明,后赋值
var name; // 声明一个变量 name name = '张三'; // 一个等号 是赋值,,后面的值赋值给前面的 console.log
-
同时声明+赋值
var name = '张三' console.log
-
同时声明多个变量并赋值
; => 代表一句代码结束 , => 并列 var age = 10,name= 'zs' // 相当于 var age = 10; var name = 'zs';
-
不声明变量,直接赋值(不会报错,但是不推荐)
// 不推荐 height=100; console.log(height);
-
不声明变量,也不赋值变量,直接使用(会报错)
// weight is not defined 要知道是没有定义,,估计是变量名写错了 console.log(heightt);
结论:
-
变量需要声明之后,才能使用,养成一个良好的编程习惯。
-
javascript代码一旦报错了,后面的代码就不再执行了。
2.变量的命名规则和规范
-
规则 : ( 必须遵守的,不遵守会报错 )
-
由字母、数字、下划线、$符号组成 ;
-
不能以数字开头
-
区分大小写
-
不能是关键字和保留字 (不用死记 , 慢慢就见多了)
//关键字:对于js来说有特殊意义的一些单词 //保留字:js保留了一些单词,这些单词现在不用,但是以后要用
-
-
规范 : (建议遵守的 不遵守不会报错)
-
变量名必须有意义
-
遵守驼峰命名法。 首字母小写,后面单词的首字母需要大写!
如:myName, userPassword
-
数据类型
javascript中数据类型分为简单数据类型和复杂数据类型,下面是简单数据类型 ( 5个 )
number、string、boolean、undefined、null
数值 字符串 布尔 声明未赋值 空类型
复杂类型 ( 3个 ) : 数组 array .. 函数 function ... 对象 object
一、number-数字类型
1.进制值 (简单了解)
在javascript中表示一个数字,除了有我们常用的十进制11, 22,33
等,还可以使用八进制、十六进制表示等。
-
十进制
//我们最常用的进制,进行算术运算的时候,八进制和十六进制最终都要转换成十进制
//逢10进1
var num = 9;
var num = 29;
-
八进制
// 0开头的数字, 逢8进1
var num1 = 07;
var num2 = 012;
// 八进制 0-7 逢八进一 , 10
var ba = 0321;
// 12 = 2*8^0 + 1*8^1 = 10
// 321 = 1*8^0 + 2*8^1 + 3*8^2 = 1+16+ 192 = 209
console.log(ba);
-
十六进制
// 0x开头的数字,逢16进1, 数字范围1-9A-F
var num = 0xA;
var num = 0x12;
tips : 关于二进制,计算机在只认识二进制,所以所有的代码最终都会转换成二进制数据。
2.浮点数
浮点数就是小数,,比如0.1
-
浮点数
var num = 0.1;
-
科学计数法
//e 10的多少此方 前面得有数字
//e+5 10^5
//e-3 10^-3
//当一次数字很大的时候,可以用科学计数法来表示
var num = 5e+5; //5乘以10的5次方
var num = 3e-3;//3乘以10的-3次方
-
浮点数精度丢失问题
//在进行浮点数运算的时候,可能会出现精度丢失的问题
0.1 + 0.2 = 0.30000000000000004;
0.2 + 0.2 = 0.4;
//尽量少用浮点数进行运算,不要让浮点数进行比较。
解决办法 : 根据小数点后面的位数量 乘以对应的整数;
0.1 + 0.2 ==> (0.1*10+0.2*10) / 10 = 0.3
0.01 + 0.02 呢?
二、字符串类型 - string
字符串类型,使用双引号 "
或者 '
包裹起来的字符
//双引号和单引号必须成对出现
var str = 'hello world';
var str = "hello world";
1.字符串长度
每一个字符串都有一个length属性,可以获取到字符串中字符串的个数
var str = "akdjflksjdflk";
console.log(str.length);
2.转义字符
思考,如何打印?
// 大家好,我姓'熏',我叫孙悟空
// 离开'他'吧, 我偷"电瓶车"养你
1. 单引号和双引号可以互相嵌套,但是不能嵌套自己
2. 使用转义符
3.字符串拼接 +
-
+
号具有字符串拼接功能,它能将两个字符串拼接成一个字符串。 -
+
号同时具有算术加法的功能,它能将两个数字进行相加 -
如果
+
号两边有一个是字符串,那么就是拼串的功能,如果都是数字,那么就是算数的功能。
// 第一种情况 : 字符串 + 字符串
var a = "hello";
var b = "itcast";
console.log(a + b);//字符串拼接功能
// 第二种情况 : 数值 + 数值
var a = 100;
var b = 100;
console.log(a + b);//加法
// 第三种情况 : 字符串 + 数值
var a = '100';
var b = 100;
console.log(a + b);//字符串拼接功能
三、布尔类型 boolean
布尔类型:true 和 false
//布尔类型只有两个值
true:表示真
false:表示假
注意:
1. 区分大小写,不要写成True或者是False了
2. 'true' 和 true , 前者是字符串类型
四、undefined和null
都属于获取非正常值的类型
-
undefined表示一个没有赋值的变量
-
null表示一个空的对象, ( 例如 : 获取一个元素,id写错了,获取不到,返回一个null)
字面量赋值 与 变量赋值
-
字面量赋值,字面量也叫直接量,值是固定不变的,浏览器能够直接识别的量,比如
11, "abc", true, false, undefined, null
等都是字面量,可以直接会使用。 -
变量赋值:浏览器必须要经过声明之后,才认识变量,如果没有声明,直接使用变量是会报错的。
运算符 (操作符)
变量可以存储数据,我们还需要学习操作符来操作这些数据
1、 算术运算符
2、 赋值运算符
3、 一元运算符
4、 逻辑运算符
5、 比较运算符
1.算术运算符
//快速的说出以下的结果?
console.log(123 + 123);
console.log("123" + 123);
console.log(123 - 123);
console.log(123 - "123");
console.log(12 * "12");
console.log(12 / 12);
console.log(10 % 2);
2.赋值运算符
赋值运算符有: = , +=, -=, *=, /=, %=
var num = 10;
num += 1; //num = num + 1; 累加
num -= 1; //num = num - 1;
num *= 2; //num = num * 2;
num /= 2; //num = num / 2;
num % = 2; //num = num % 2;
3.一元运算符
一元运算符:只有一个操作数的运算符
二元运算符:有两个操作数的运算符,比如算术运算符、赋值运算符
自增运算符:++
-
先自增:
++i
+在前 先自增,,再使用 -
后自增:
i++
i在前 先使用,再自增
异同点 :
1. 相同点 : 代码执行之后, 数值都会 + 1
2. 不同点 : 就是在自增的时候使用就会出现不同
//先自增:
var num = 1;
console.log(++num); //先自增:表示先加1,后返回值
//后自增:
var num = 1;
console.log(num++);// 后自增:表示先返回值,后+1
自减运算符:--
-
先自减:
--i
-
后自减:
i--
4.逻辑运算符
-
&&
:与运算符,表示且,只有当两个操作数都为true
的时候,结果才是true
一个为真,,并且 另外一个也为真 => 结果才为真
-
||
:或运算符,表示或,只要有其中一个操作数是true
,结果就是true
一个为真,,或者另外一个为真,,, 结果就可以为真
-
!
:非运算符,取反
console.log( true && true );
console.log( false && true );
console.log( true && false );
console.log( false && false );
console.log( true || true );
console.log( false || true );
console.log( true || false );
console.log( false || false );
console.log(!true);
console.log(!false);
总结 :
&& 翻译 : 一个为真,且,,另外一个也为真 => 才为真
1. 两者都为true,才为true
|| 翻译 : 一个为真,或者另外一个为真 => 真
1. 两者有一个为true,结果就为true
5.比较运算符
比较运算符也叫关系运算符, < > >= <= == != === !==, 关系运算符的结果是布尔类型
var a = 5;
var b = 6;
console.log(a > b);//大于
console.log(a < b);//小于
console.log(a >= b);//大于等于
console.log(a <= b);//小于等于
console.log(a == b); //相等,只比较值,不比较类型
console.log(a === b); //全等,比较类型和值
console.log(a != b); // 不等, 只判断值,不判断类型
console.log(a !== b); // 不全等 判断值,且判断类型
注意 :
数字类型比较和字符串比较是由区别的
// 主要涉及到数字就是比较内容
1. 数字比较 : 24>3; 比较数字大小
2. 字符串比较 : '24' < '3' 比较首字母大小
3. 字符串和数字混合比较 : 比较数字内容大小
6.运算符优先级
-
()
的优先级最高 -
一元运算符(++, --, !)
-
算术运算符(先
*/%
, 后+-
) -
比较运算符 (先
> < >= <=
, 后== === != !==
) -
逻辑运算符(先
&&
后||
)
类型转换
一、为什么要进行类型转换?
服务器拿回来的数据,有可能是字符串,比如age='18',
var age = '18';
console.log(age+1);
二、查看变量的类型
typeof关键字可以查看数据的类型
var num = 11;
console.log(typeof num);
num = "abc";
console.log(typeof num);
小技巧:在控制台可以根据颜色来判断数据的类型哦(^__^)
三、转换成 数值类型 -number
-
1 Number()
console.log(Number('55'));
Number()可以把任意值转换成数值类型,但是如果字符串中有不是数字的字符,返回NaN
-
2 parseInt() 和 parseFloat()
- parseInt() 把整数或者小数都转化为整数;
- parseFloat() 把整数转化整数,把小数转化为小数
var num1 = parseInt("12"); // 12
var num1 = parseInt("12.3"); //12
var num1 = parseFloat("12"); //12
var num1 = parseFloat("12.3");//12.3
var width = '100px';
parseInt(width) => 100
-
3 算术运算 (最常用)
var str = '500';
console.log(+str); // 取正
console.log(-str); // 取负
console.log(str - 0); +0呢???拼接
四、转换成 字符串类型 - string
-
1 String()
var num = 5;
num = String(num);
console.log(num);
-
2 toString()
var num = 5;
console.log(num.toString());// 把数值5变成字符串5
//将来所有的数据都会有toString()方法,除了null和undefined
-
3 拼串,(最常用)
var num = 5;
num = num + "";
console.log(num);
五、转换成布尔类型
所有的值都可以转换成布尔类型
其中 0
, ""
, undefined
,null
,false
, NaN
,这几个值会转换成false,其他值都会转换成true
这个代表的五大基本类型
// 没有值 => false
// 有值 => true
// number string boolean undefined null
// 0 ''
注意 :
1. 'false' 它是字符串
2. NaN => false
-
Boolean()
console.log(Boolean(1));
console.log(Boolean(0));
-
!!
var a = "abc";
console.log(!!a);
六、NaN
NaN: not a number, 表示一个非数字
比如:var num = parseInt('abc')
在js中,NaN用来表示一个非数字的特殊值,当发现无法进行运算时,js不会报错,而是会返回一个NaN
NaN的注意事项:
-
NaN的类型是number类型的,表示一个非数字
-
NaN不等于任何值,包括NaN本身
-
通过isNaN()可以判断是否是一个数字,返回false的时候,表示是一个数字
流程控制
分支语句 (3个)
分支语句目的 : 解决不同条件不同效果的问题
第1个分支语句 : if语句 (★★★★★)
-
单独的if语句 ==> 可能性只有一种
// 语法 if (条件) { // 只有当条件为 true 时,执行代码 }
-
if..else 语句 ==> 可能性有2种
// 语法 if (条件) { // 当条件为 true 时执行的代码 }else { // 当条件不为 true 时执行的代码 }
-
if..else if ..else 语句 ==> 可能性有2种以上
if (条件1) { // 当条件1为 true 时执行的代码 }else if (条件2){ // 当条件2 为true 时执行的代码 }else { // 当条件1和 条件2 都不为true 时执行的代码 }
第2个分支语句 : 三元运算符 (★★★★)
条件 ? 值1 : 值2 /*或者*/ 条件 ? 表达式1 : 表达式2
1. 三元运算符会得到一个结果,结果根据`条件`来确定。
2. 如果`条件`的值为true,会返回表达式1的值/值1
3. 如果`条件`的值为false,会返回表达式2的值/值2
第3个分支语句 :switch语句 (★)
if..else适用于范围的判断,switch..case适用于具体的值的判断
语法格式 :
switch case break default
switch (变量) {
case 值1:
语句1;
break;
case 值2:
语句2;
break;
case 值3:
语句3;
break;
…
default:
默认语句;
break;
}
注意 :
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串'10' 不等于数值 10)
使用场景
-
如果是范围性的判断,使用if..else会更加方便
-
如果是对具体值的判断,使用switch..case语句会更加方便,当然用if..else也是可以的。
-
如果if..else比较简单,可以使用三元运算符进行替代。
循环语句 (3个)
在javascript中,循环语句有三种,while、do..while、for循环。
循环语句的目的 : 解决需要重复执行某些语句的代码
第1个循环语句 : while循环 (★★)
基本语法 :
//当循环条件为true时,执行循环体,
//当循环条件为false时,结束循环。
while(循环条件){
//循环体:需要循环执行的语句
}
代码示例:
//1. 打印1-100之间所有的数 (讲)
//2. 计算1-100之间所有数的和 (讲)
// 初始化变量
var i = 1;
var sum = 0;
while(i <= 100){//判断条件
sum += i;//循环体
i++;//自增,修改循环条件(不能省略)
}
console.log(sum);
第2个循环语句 : do..while循环 (★)
do..while循环和while循环非常像,二者经常可以相互替代,但是do..while的特点是不管条件成不成立,都会执行一次。
基础语法 :
do {
//循环体;
}while(条件)
代码示例 :
//初始化变量
var i = 1;
var sum = 0;
do{
sum += i;//循环体
i++;//自增
}while(i <= 100);//循环条件
第3个循环语句 : for循环 (★★★★★)
写while循环的经常会忘记自增,for循环其实是while循环演化过来的,语法更加的简洁明了,使用非常的广泛。
for循环语法:
//1. for循环使用分号分隔
//2. for循环有2个分号,两个分号不能少
for(初始化语句;判断语句;自增语句){
//循环体
}
执行顺序:1243 ---- 243 -----243(直到循环条件变成false)
-
初始化语句
-
判断语句
-
自增或者自减
-
循环体
break和continue
break: 结束/中止for循环
立即跳出当前整个循环,即循环结束,开始执行循环后面的内容(直接跳传出大括号)
一般写在打印之后
continue: 结束本次循环,进行下一个循环
立即跳出当前循环,继续下一次循环(跳到i++的地方) (放打印代码前面)
一般写在打印之前
数组
-
所谓数组, 就是将多个元素,按一定顺序排列放到一个集合中 , 那么这个多个元素的集合我们就称之为数组
-
特点 : 有顺序,有长度;
-
用途 : 存储大量的数据
-
总结 :
数组 : 多个元素的集合,,这个集合有顺序,有长度。用途是存储大量的数据.
创建数组
-
通过 构造函数 创建数组
var arr = new Array();//创建了一个空数组 var arr = new Array(1,2,3,4);//创建了一个数组,里面存放了4个数字 var arr = new Array(4);//创建了一个数组,长度为4,里面全是空值
-
通过 数组字面量 创建数组
var arr1 = []; //创建一个空数组 var arr2 = [1, 2 , 3, 4]; //创建一个包含4个数值的数组,多个数组项以逗号隔开 var arr3 = [4]; // 创建一个数组,元素只有1个,,,元素是4
数组的长度与下标
-
数组的长度 : 跟字符串一样,,,数组有一个length 属性,, 指数组中存放的元素的个数 ;
var str1 = 'abc'; console.log(str1.length); var arr = [1,3,5,8]; console.log(arr.length);
-
数组的下标 : 因为数组有序的,有序的就应该有自己的序号,,而这个序号就是每个元素对应的下标, 下标从0 开始 , 到 arr.length-1 结束
var arr = ["zs", "ls", "ww"]; arr[0];//下标0对应的值是zs arr[2];//下标2对应的值是ww var arr = ['zs','ls','ww']; // 3-1 = arr.length-1 // 0 1 2 // 1. 开始 : 0 // 2. 结束: arr.length-1 // 下标范围 : 0 ~ arr.length-1 死记住 后面遍历会用到这个范围
数组的取值与赋值
-
数组的取值
//格式:数组名[下标] //功能: 获取数组下标对应的那个值,如果下标不存在,则返回undefined。 // 下标范围 : 0 ~ arr.length-1 var arr = ["red", "green", "blue"]; // 打印 : arr[0];//red 打印 : arr[2];//blue 打印 : arr[3];//这个数组的最大下标为2,因此返回undefined
-
数组的赋值
//格式:数组名[下标] = 值; //如果下标有对应的值,会把原来的值覆盖, var arr = ["red", "green", "blue"]; arr[0] = "yellow";//把red替换成了yellow // 如果下标不存在,会给数组新增一个元素。 arr[3] = "pink";//给数组新增加了一个pink的值 // 如果下标有跨度,,中间全是empty 不合法 // 特殊 : arr[arr.length] = 值 arr[arr.length] = '哈'; arr[arr.length] = '你妹';
函数
函数的声明与调用
就相当于之前数组的创建和使用
声明函数的语法 :
function 函数名() {
// 函数体
}
调用函数的语法 :
函数名
函数名()
特点:
1. 函数声明的时候,函数体并不会执行,函数体只有在调用的时候,才会执行;
2. 可以调用多次;
代码示例 :
// 声明函数
function sayHi() {
console.log('萨瓦迪卡');
}
// 调用函数
sayHi();
函数的参数
function getSum() {
var a = 10;
var b = 20;
console.log(a+b);
}
// 打印的是 10+20
getSum();
// 想打印 20+30? 怎么办????
getSum();
-
形参 ( 形式参数 ) : 在函数声明时, 设置的参数。作用是占位置 。只能在函数内部使用.
-
实参 ( 实际参数 ) : 在函数调用时,传入的参数。 作用 : 函数调用时,会把实参的值赋值给形参, 这样形参就有了值, 在函数体里,,,可以直接使用形参! (可以是number string boolean等)
语法 :
//带参数的函数声明
function 函数名(形参1, 形参2, 形参...){
//函数体
}
//带参数的函数调用
函数名(实参1, 实参2, 实参3);
如何确定形参:
在声明函数的时候,碰到不确定的值的时候,就可以定义成形参。
注意:
-
形参在声明时,值不固定,只有在调用的时候,形参的值才确定,形参的值会跟着函数调用时的实参不一样而不一样。
-
如何确定形参:在声明函数的时候,碰到不确定的值的时候,就可以定义成形参。
函数的返回值
当函数执行完的时候,我们期望函数给我一些反馈(比如计算的结果),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值
返回值语法:
//声明一个带返回值的函数
function 函数名(形参1, 形参2, 形参...){
//函数体
return 返回值;
}
//可以通过变量来接收这个返回值
var 变量 = 函数名(实参1, 实参2, 实参3);
函数返回值注意事项:
-
return后面的语句不执行。
-
函数可以没有返回值,函数如果没有return,那么返回结果是undefined。
-
函数的参数可以有多个,但是返回值只能有1个。
函数三要素
函数三要素包括:函数名、参数、返回值
注意 : 参数和返回值可以没有,,,但是函数名一定要有;
函数也是一种类型
声明函数的两种方式
方式1 : 函数声明:
function 函数名(){
//函数体
}
方式2 : 函数表达式 ( 匿名函数 )
var 函数名 = function(){
//函数体
}
函数可以作为参数
通常,我们把作为参数传递的函数叫做回调函数
function fn1(fn) {
fn();
}
fn1(function(){
console.log("哈哈");
});
函数可以作为返回值
在js高级中,闭包会使用到。
function fn1() {
return function(){
console.log("呵呵");
}
}
fn1()();//调用
作用域 ★
作用域:变量起作用的区域
全局作用域 :在script标签内,函数外的区域就是全局作用域,在全局作用内声明的变量叫做全局变量 。全局变量可以在任意地方访问。
函数作用域 :在 函数内的区域 叫做函数作用域,在函数作用域内声明的变量叫做局部变量 ,局部变量只有在当前函数内才能访问到。
全局变量:在函数外,script标签内声明的变量就是全局变量,全局变量在任何地方都能访问的到。
局部变量:在函数中声明的变量,就是局部变量,局部变量只有在当前函数体内能够访问。
隐式全局变量:没有使用var定义的变量也是全局变量,叫做隐式全局变量。(不要使用)
预解析 ★
console.log(num4);
// var num4 = '123';
js执行代码分为两个过程:
-
预解析过程(变量与函数提升)
-
代码一行一行执行
预解析过程:
// 1. 把var声明的变量提升到当前作用域最前面,不会提升赋值 var num = 19 ; var fn = function() {..}
// 2. 把函数声明 提升到当前作用域的最前面,, function test() {....}
// 3. 如果函数同名 ??? 后者会覆盖前者 (帅)
// 4. 如果 var声明的 和 函数声明的同名 , 函数覆盖var声明的
匿名函数与自调用函数 ★
匿名函数
匿名函数:没有名字的函数
匿名函数如何使用:
1. 将匿名函数赋值给一个变量,这样就可以通过变量进行调用
- 函数表达式
- 函数作为参数
- 函数作为返回值
2. 自执行(匿名函数自执行)
匿名函数自执行的作用:防止全局变量污染。
对象
什么是对象??
现实生活中 : 万物皆对象, 对象是一个具体的事物 , 一个具体的事物就会有 特征 和 行为 ;
JavaScript中: js中的对象就是生活中对象的一个抽象,,,, 没有特征和行为,,取而代之的是有对应的属性和方法 ;
-
对象 : 是一组无序的键值对的集合
-
特点 :
1. 声明的变量 = {} []=> 数组 2. 键值对出现 3. 逗号隔开,, 记住 : 以后再 {} 内一行一行的都是用 , 隔开
对象:是一组无序的键值对的集合。 对象用于存放一组无序的数据,比如一个人的特征和行为。
//数组多个元素之间使用,隔开
//对象中多个键值对之间也用,隔开,,,键值对的格式: 键:值
var obj = {
name:"张三",
age:18,
sex:"男",
hobby:"上网"
}
创建对象-1 (2种方式 单创)
单纯的创建一个对象
对象字面量
字面量 : 直接量,,,通过看数值,,直接看出来类型的 ,或者不需要通过创建, 11, '234', true , [] , {}
var p = {};
var p = {
name : 'zs',
age:18,
sayHi:function(){
console.log(this.name)
}
}
注意 :
this使用在对象的属性的函数里,,其实地方使用没有意义
通过Object构造函数创建
var p = new Object(); // 创建一个空的对象
var p = new Object({name :'xx'});
设置对象的属性
// 语法 对象名.属性 = 值
var obj = new Object();
// 添加属性
obj.name = 'zs';
obj.age = 18;
obj.gender = '男';
// 添加方法
obj.sayHi = function () {
console.log('大家好,我是' + obj.name);
}
// 设置对象的属性的语法
// 对象.属性 = 值
// 1. 如果对象有这个属性,修改这个属性
// 2. 如果对象没有这个属性,添加这个属性
获取对象的属性
// 语法 对象名.属性
console.log(obj.name);
console.log(obj.age);
console.log(obj.gender);
//如果是方法,可以调用
obj.sayHi();
// 获取对象属性的语法:
// 对象.属性:对象的属性
// 1. 如果有这个属性,直接返回属性值
// 2. 如果没有这个属性,返回undefined
删除对象属性
delete关键字可以删除对象的属性
var obj = {name:"zs", age:18}
delete obj.name;//删除obj的name属性
创建对象-2 (2种方式 批量)
批量创建对象
在实际开发中,经常需要创建多个相同类型的对象,比如游戏中的怪物,班级的学生等。
使用工厂函数创建对象
//定义一个函数,用于创建学生对象
//工厂函数:
function createStudent(name, age, sex) {
//1.创建空对象
var stu = {};
//2. 赋值
stu.name = name;
stu.age = age;
stu.sex = sex;
stu.sayHi = function() {
console.log("大家好,我是"+this.name);
}
//3 . 返回
return stu;
}
var stu1 = createStudent("zs", 18, "男");
stu1.sayHi();
优点:可以同时创建多个对象
缺点:创建出来的没有具体的类型,都是object类型的
查看一个对象的类型
typeof 只能判断基本数据类型的类型
instanceof 判断对象的具体类型
constructor.name 也可以获取到对象的具体类型
关于typeof
-
typeof用于查看基本的数据类型, number string boolean undefined
-
typeof如果查看复杂数据类型,返回的都是object类型。
-
typeof null比较特殊,结果是object
-
typeof 函数的结果是function:因为函数是一等公民
// 简单类型
var num1 = 12;
var num2 = 'abc';
var num3 = true;
var num4 = undefined;
var num5 = null; //(object类型)
// 复杂类型 (引用类型)
function num6() {
}
var num7 = [];
var num8 = {};
方式2 : instanceof 判断
结构 : 对象 instanceof 构造函数
var arr = [];
var obj = {}
var fn = function () {}
console.log( arr instanceof Array); // true
console.log( obj1 instanceof Object);// true
console.log( fn instanceof Function);// true
方式3 : constructor.name
// 原型的构造函数
console.log(arr.constructor.name); //Array
console.log(obj1.constructor.name); //Object
console.log(fn.constructor.name); //Function
自定义构造函数
工厂函数的缺点 就是无法确定对象的具体类型
构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
//所有创建出来的对象都有:
//name
//age
//hobboy
function Teacher(name, age) {
//构造函数内部的this指向的是新创建的那个对象
this.name = name;
this.age = age;
}
var tea = new Teacher("zs", 18);
console.log(tea);
-
构造函数首字母要大写(推荐做法)。
-
构造函数要和new一起使用才有意义。
-
构造函数的作用是用于实例化一个对象,即给对象添加属性和方法。
new在执行时会做四件事情
//1. new会创建一个新的空对象,类型是Teacher
//2. new 会让this指向这个新的对象
//3. 执行构造函数 目的:给这个新对象加属性和方法
//4. new会返回这个新对象 构造函数的作用(实例化对象): 给创建出来的对象增加属性和方法。
操作对象的属性
.语法 ----- 对象名.属性名 ( 看似变量,不是字符串 )
// 获取对象属性的语法:
// 对象.属性:对象的属性
// 1. 如果有这个属性,直接返回属性值
// 2. 如果没有这个属性,返回undefined
// 设置对象的属性的语法
// 对象.属性 = 值
// 1. 如果对象有这个属性,修改这个属性
// 2. 如果对象没有这个属性,添加这个属性
[]语法 ---- 对象名 [ 属性字符串 ] (字符串)
var key = 'name';
console.log ( obj['name'] ) // ok
console.log ( obj[name] ) // X
console.log ( obj[key] ) //ok
二者的区别:当属性名是一个字符串存储在变量中的时候,只能使用关联数组的方式。
应用场景 : 遍历对象
遍历对象
通过for..in语法可以遍历一个对象
for (var key in obj) { // 键 console.log(key); // 值 console.log(obj[key]); }
判断一个属性是否是对象的一个属性
-
结构 :
if (属性名 in 对象) { .. }
-
代码
var obj = {
name: 'zs'
}
if ('name' in obj) {
console.log('是');
}
获取对象里的所有属性
// 结构 : Object.keys(对象)
Object.keys(obj)
值类型与引用类型
JS数据类型
简单数据类型:number、string、boolean、undefined、null
复杂数据类型:Array、function, Object
简单数据类型也叫值类型,复杂数据类型也叫引用数据类型,这主要是根据内存存储方式来区分的。
-
变量在存储简单类型的时候,存的是值本身(值类型)
-
变量在存储复杂数据类型的时候,存的是引用,也叫地址(类型)
值类型的存储 - 画图全
变量存储数据的时候,存储的直接就是这个值本身。
var num = 12;
var str = 'abc';
var b = true;
简单类型进行赋值的时候,赋值的是值本身。
引用类型的存储-arr obj-fn
复杂类型: 变量不会存这个对象,对象随机存在内存中,会有一个地址,变量存储的仅仅是这个对象的地址。
var arr = [1,2,3];
var obj = { name : 'zs' }
var fn = funtion () {...} 不过一般函数function () {...} 一般不写引用类型
内置对象
JS内置对象就是指Javascript自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。
Math对象
Math对象中封装很多与数学相关的属性和方法。
-
π
Math.PI
-
最大值/最小值
Math.max(); Math.min();
-
取整(★) [1.1 , 1.9, -1.1 , -1.9 , 1.5]
Math.ceil();//天花板,向上取整 Math.floor();//地板,向下取整 Math.round();//四舍五入,如果是.5,则取更大的那个数
-
随机数(★★)
Math.random();//返回一个[0,1)之间的数,能取到0,取不到1 // 一般情况看下,我们不是要求随机小数,一般整数,例如速记点名
-
绝对值 (abs absolute 绝对) (★)
Math.abs();//求绝对值
-
次幂和平方 (pow power 幂 sqrt:开方 )
Math.pow(num, power);//求num的power次方 Math.sqrt(num);//对num开平方
Date对象
Date对象用来处理日期和时间
-
创建一个日期对象
var date = new Date();//使用构造函数创建一个当前时间的对象 var date = new Date("2017-05-22");//创建一个指定时间的日期对象 var date = new Date("2017-03-22 00:52:34");//创建一个指定时间的日期对象 var date = new Date(2017, 2, 22, 0, 52, 34); var date = new Date(1523199394644);//参数:毫秒值 Date构造函数的参数 1. 毫秒数 1498099000356 new Date(1498099000356) 2. 日期格式字符串 '2015-5-1' new Date('2015-5-1') 3. 年、月、日…… var date = new Date(2017, 2, 22, 0, 52, 34);月份从0开始
-
日期格式化(了解)
date.toLocaleString();//本地风格的日期格式 date.toLocaleDateString(); // 获取日期 date.toLocaleTimeString(); // 获取时间
-
获取日期的指定部分 (★)
getMilliseconds();//获取毫秒值 getSeconds();//获取秒 getMinutes();//获取分钟 getHours();//获取小时 getDay();//获取星期,0-6 0:星期天 getDate();//获取日,即当月的第几天 getMonth();//返回月份,注意从0开始计算,这个地方坑爹,0-11 getFullYear();//返回4位的年份 如 2016
-
时间戳
-
实际项目中,用的最多的就是时间戳,,因为这个好计算,其他的都不好算
var date = +new Date();//1970年01月01日00时00分00秒起至现在的总毫秒数 //思考 //如何统计一段代码的执行时间? 打印10000次 // 开始 var start = +new Date(); for ( var i = 1 ; i <= 1000 ; i++) { console.log(i); } // 结束 var end = +new Date(); console.log('时间戳 :' + (end-start));
Array对象
数组对象在javascript中非常的常用
-
数组转换(★)--- join
//语法:array.join(分隔符) //作用:将数组的值拼接成字符串,并且返回字符串 var arr = [1,2,3,4,5]; arr.join();//不传参数,默认按【,】进行拼接 arr.join("");//按【"】进行拼接 arr.join("-");//按【-】进行拼接
-
数组的增删操作(★)
var arr = ['zs','ls','ww'] array.push(元素);//从后面添加元素,返回新数组的length array.pop();//从数组的后面删除元素,返回删除的那个元素 array.unshift(元素);//从数组的前面的添加元素,返回新数组的长度 array.shift();//从数组的最前面删除元素,返回删除的那个元素 //总结: //1. shift 在前面 ,所以处理数组前面的 //2. p+ 在后面,所以是处理后面的 //3. unshift 比 shift 多个un,,所以就是加 //4. 添加的都是返回长度 //5. 删除的都是返回删除的元素 //6. 添加要说明添加什元素,,删除直接删除
-
数组的翻转与排序
array.reverse();//翻转数组 array.sort();//数组的排序,默认按照 字母/首字符 顺序排序 => 1 11 2 3 var arr1 = ['a','d','b','c']; var arr2 = [3, 6, 1, 5, 10, 2,11]; //sort方法可以传递一个函数作为参数,这个参数用来控制数组如何进行排序
-
数组的拼接与截取
//1. concat:数组合并,不会影响原来的数组,会返回一个新数组。 var newArray = array.concat(array2); //2. slice:截取出来,既然是截取`出来`,,肯定要有个东西接收 //原来的数组不受影响, // - slice() 全部截取出来 // - slice(begin) 从第begin往后截取出来 // - slice(begin, end) 从第begin开始删除,,不包括end [start, end) var arr = ['zs','ls','ww','zl','xmg']; var newArray = array.slice(begin, end); //3. splice : 数组任意地方删除或者添加元素 var arr = ['zs','ls','ww','zl','xmg']; // 原来的数组影响 //- splice(start, deletedCount) 删除元素 // - start 开始 // - deletedCount 删除个数 //- splice(start, deletedCount , item) 删除+添加, 第三个参数是在原来删除的位置上新加几个元素 //- 特殊 : // splice(start, 0 , item) 就是在某个位置新加元素
+ 数组查找元素
```javascript
//indexOf方法用来查找数组中某个元素 `第一次`出现的位置,如果找不到,返回-1
array.indexOf(search, [fromIndex]);
//lastIndexOf()方法用来查找数组中某个元素 `最后一次`出现的位置,如果找不到,返回-1
array.lastIndexOf(search, [fromIndex]);
var arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
主要配合if语句的多
-
清空数组
//1. array.splice(0,array.length);//删除数组中所有的元素 //2.array.length = 0;//直接修改数组的长度 //3.array = [];//将数组赋值为一个空数组,推荐
基本包装类型
简单数据类型是没有属性和方法的。为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean。
基本包装类型:把基本类型包装成复杂类型。
var str = “abc”;
var result = str.indexOf(“a”);
//发生了三件事情
1. 把简单类型转换成复杂类型:var s = new String(str);
2. 调用包装类型的indexOf方法:var result = s.indexOf(“a”);
3. 销毁刚刚创建的复杂类型
总结 : js为了我们使用方便,浏览器允许使用简单类型直接调用方法,会自动把简单类型转换成复杂类型。
Number对象
Number对象是数字的包装类型,数字可以直接使用这些方法
toFixed(2)//保留2位小数
toString();//转换成字符串
Boolean对象
Boolean对象是布尔类型的包装类型。
toString( );//转换成字符串
undefined和null没有包装类型,所以调用toString方法会报错
String对象
字符串可以看成是一个字符数组(伪数组)。因此字符串也有长度,也可以进行遍历。String对象很多方法的名字和和Array的一样。可以少记很多的单词。
注意: 注意 : 操作字符串的方法都不会改变原来的字符串,,所以需要返回
-
查找指定字符串
//indexOf:获取某个字符串第一次出现的位置,如果没有,返回-1 //lastIndexOf:获取某个字符串最后一次出现的位置。如果没有,返回-1
-
去除空白
trim();//去除字符串两边的空格,内部空格不会去除
-
大小写转换
//toUpperCase:全部转换成大写字母
//toLowerCase:全部转换成小写字母
-
字符串拼接与截取
//字符串拼接 //可以用concat,用法与数组一样,但是字符串拼串我们一般都用+ //`字符串截取`的方法有很多,记得越多,越混乱,因此就记好用的就行 //slice :截取出来 从start开始,end结束,并且取不到end。 `和 substring一样` //substring :从start开始,end结束,并且取不到end //substr : :从start开始,截取length个字符。 == 数组的 splice() 总结 :优先使用 substr
-
字符串切割
//split:将字符串分割成数组(很常用) //功能和数组的join正好相反。 var str = "张三,李四,王五"; var arr = str.split(",");
-
字符串替换
var str = 'abcedabc' str = str.replace(/a/g,'c') replace(searchValue, replaceValue) // replace(old, new) //参数:searchValue:需要替换的值 replaceValue:用来替换的值