数据类型
1.数字类型Number
包括整数和浮点数
特殊数字类型 Infinity -Infinity NaN(not a number)
当计算不出结果时就会显示NaN
<!--下面的不会报错,但计算不出结果-->
console.log("你好" / 2 )
2.字符串String
特征:只要带引号,单双引号都可以,``反引号也可以表示, 不同类型的引号是可以嵌套的,但同类引号不能嵌套
3.布尔类型Boolean
只有两种类型,true,false
4.undifend类型
只有一个值undefined (未定义)
当一个变量,只声明,但没有赋值的时候,他的值就是undifined
var a;
console.log(a) //输出结果是undefined
5.null类型
只有一个值 null表示空
引用数据类型
1.数组类型Array
[] 元素 一般表示同一类型的数据集合
//字面量创建
var arr = ["张三", "李四", "王五"];
2.对象类型 Object
保存信息 特征: {属性名:属性值}
var User= {
name:"张三",
age:18,
}
3.函数function
function getUserInfo(){
alert("你好");
}
4.typeof检测变量数据类型
var num = 10;
console.log(typeof num); //输出number
<!--要注意的是检测值为null的变量时会输出object,历史遗留问题-->
<!--array其实也是一种特殊的对象-->
<!--这种方法不能检测null和数组-->
5.数据转换
console.log(20 + 10);//输出30
console.log(20 - "hellow"); //输出NaN
console.log(20 - "10"); //输出10
consloe.log(20 + "10"); //输出2010
以上涉及到一些数据之间的隐式转换.
隐式转换的规则:
1.其他数据类型==>转成字符串
//方法一:利用String()可以将括号里面的数据喜欢换成字符串类型
//方法二:toString() 括号里不填
var num = 100;
consloe.log(String(num)); //输出"100"
consloe.log(num.toString()); //输出"100"
//对于null undefined不能使用toString(),可以使用String()
2.其他数据类型==>转成字符串Number()
var str = "hello";
var flag = true;
var a;
var c = null;
console.log(Number(str)); //输出NaN
console.log(Number(flag)); //输出1
console.log(Number(a)); //输出NaN
console.log(Number(c)); //输出0
//数组字符串能够转化成数字,其他的都转换成NaN
console.log(Number("100")); //输出100
//空字符串
console.log(Number("")); //输出0
//全是空格的字符串
console.log(Number(" ")); //输出0
3.其他数据类型==>转成字符串
//Boolean() 只有五种会变成false 0 NaN undefined null ""
console.log(Boolean(null)); //输出false
console.log(Boolean(undefined)); //输出false
console.log(Boolean(100)); //输出true
console.log(Boolean(NaN)); //输出false
6.parseInt和parseFloat
//parsetInt是用来对付字符串的,作用是将字符串中的有效整数内容转化为数字
//必须以数字开头,否则就会转化成NaN
//自定带有截断小数的功能,取整,不四舍五入
//如果对不是字符串的使用parsetInt(),那么会将其先转换成字符串然后再操作
console.log(parseInt("24.8px")); //输出24
parsetFolat();转化同parsetInt相似,但识别小数
运算符
1. 赋值运算符,把右边的值赋值给左边的变量
var a = 10;
a = 50;
//+= *=
var c= 10;
c = c + 5; //可以简写成c+=5;
// ++ --
c = c + 1 //简写成 c++;或者++c
var a = 10;
var b = a++;//输出a = 11, b = 10
var m = 10;
var n = ++m; //输出 m = 11, n = 11
//当只用自加或者自减时,都是一样的.当赋值给另外一个变量时,就会有区别
2.算术运算符
+ - * / () %(取余)
如果参与的全是数字,则就是正常的数学运算
如果是非数字类型参与运算,则会发生隐式转换(会把非数字转换成数字 然后运算)
NaN参与的运算永远是NaN
做加法运算时,如果有字符串参与,都会转换成字符串(不再转化为数字)
3.比较运算
> < >= <= ==(判断是否相等) !=
比较运算只能两个结果 true false
如果有非数字类型参与比较:
1.一般会隐式转化为数字,然后比较
2. 特殊情况:如果比较的两个值都是字符串时,不会将其转化为数字进行比较
3.相等判断 == === != !==(严格不等于)
console.log(5 == "5"); //输出true.因为字符串隐式转换成了数字
== 是存在隐式转换的,有可能并不是严格意义的相等
=== 严格的相等(不存在隐式转化) 判断是最好使用这个
console.log(5 === "5"); //输出false
4.特殊情况
consloe.log(null == undefined); //输出true
consloe.log(null === undefined); //输出false
consloe.log(null >= 0); //输出true 存在隐式转换
consloe.log(null > 0); //输出false //存在隐式转化
consloe.log(null == 0); //输出false 不存在隐式转换
4.逻辑运算
& || !
var str = "hello";
console.log(!str);//输出false. 把str先隐式的转化为布尔值,再取反
Math对象的用法
Math.abs() 求绝对值
Math.floor() 向下取整
Math.ceil() 向上取整
Math.max() 求一组数中的最大值
Math>min() 求一组数中的最小值
Math.pow(x,y) 求x的y次方
Math.sqrt() 对一个数进行开方运算
Math.round() 对一个数四舍五入去取整数
Math.random() 随机数[0,1)
随机取[m,n]之间的所有整数,m,n都是整数:
Math.floor(Math.random()*个数)+最小值
Math.floor(Math.random()*(n-m+1))+m
如[3,7]之间的随机数
Math.floor(Math.random()*5)+3
Date 日期
//获取当前日期
var nowDate = new Date();
//构造过去某个时间的对象
var date1 = new Date("2020-03-26 9:13:00");
//推荐的日期字符串格式
var date2 = new Date("2020/8/15"); //不传时间,默认0点
//取年份
var year = nowDate.getFullYear(); //输出日期的年份
var month= nowDate.getMonth(); //获取的月份是从1开始到11结束,用的时候记得加1
....
1秒 = 1000毫秒
时间戳:获取这个时间距离1970年1月1日0:0:0(格林威治时间)的毫秒数
var stamp = nowDate.getTime(); //获取某个时间的时间戳
var = nowstamp = Date.now(); //获取现在时间的时间戳
拼接字符串补充
正常的拼接
var year = 2021;
var month = 3;
var day = 27;
var dateStr1 = "当前时间:" + year + "年" + month + "月" + day + "日";
//在es6中可以直接用${变量}这种方式拼接,类似flutter中的字符串字面量的写法
var dateStr2 = "当前时间:${year}年${month}月${day}日"
流程控制
//if后面括号里面的代码具有隐式转换的功能
if(判断条件){
条件符合要执行的代码
}else{
条件不符合执行的代码块
}
//三元运算符.条件成立,返回值1,否则返回值2
条件表达式 ? 值1 : 值2
//while循环: 当符合条件时 就执行
while(条件表达式){
执行的代码
}
//do while 先执行代码,再进行条件判断.至少会执行一次
do{
执行代码
}while(条件表达式)
//for循环
for(){
执行的代码
}
//break continue 退出循环的区别
break 退出循环体,不再进行
continue 退出本次循环,不再往下进行,接着再进行下一次循环
//switch语句
switch(x){
case vale1:
...
break;
case vale2:
...
break;
default:
...
break;
}
//for of 相当于swift中的for in快速遍历
for(var a of array){
console.log(a);
}
断点调试流程
1.运行一遍程序,打开控制台
2.点开source.找到要调试的文件
3.设置和终点.打上断点
4.运行程序,点击右侧下一步的箭头
5.运行过程中观察值的变化,以及程序走的流程
字符串
charAt() //获取相应位置的字符串
charCodeAt() //指定位置字符的Unicode编码
indexOf() //返回字符在字符串中的位置
lastIndexOf() //返回字符在字符串的索引,倒序查找
concat()//连接字符串
slice() //截取字符串的某个部分
substr(2,3) //截取字符串,参数分贝代表开始位置,截取的位数
toUpperCase() //转大写字母
toLowerCase() //转小写字母
length //获取字符串的长度
//字符串也可以借助于[]语法获取对应索引位置上的字符
以上和数组中的用法相似
数组
//数组用于存储数据
//可以存储任意类型,但一般情况下数组保存的是同一类数据的集合
var arr = ["zhangsan","lisi"];
//创建空数组的良好总方法
1.通过字面量方式创建
var array = [];
2.通过创建对象的方式
var array = new Array();
//数组的长度属性
var count = array.length;
//数组的索引,从0开始
console.log(arr[0]);//输出"zhangsan"
//数组的基本操作
var ueserArray = ["张三","李四","王五"];
var user1 = userArray[1]; //获取元素
userArray[2] = "王二"; //修改元素
userArray.splice(0,1); //删除一个元素 第一个数字代表删除的开始索引 第二个数字代表删除的个数
reverse() //翻转数组
* slice(),//截取数组,指定开始索引和结束索引,但不包含结索引位置上的值,返回截取到的数组:slice(1,4).如果最后一个参数不写,就是截取到最后
* arr.includes(item,from) //从索引from的位置开始索引item,如果有返回true,没有返回false
from不填,就代表整个数组搜索
* indexOf("a") //获取字符a在数组中的索引 如果没有该元素返回-1,默认从前往后匹配,匹配到一个就返回
* lastIndexOf("a") //同indexOf相似,只不过是倒序进行匹配
* Array.isArrsy(arr) //判断一个元素是否是数组,是的话返回true,不是返回false
sort() 里面需要传一个函数,定义排序的规则
arr.sort(function (a,b){
return a-b;
})
1.数组的方法:
push 在数组末端添加元素,返回值是新数组的长度
unshift 在数组的起始位置添加元素,使用方法和push一样.返回值是删除掉的元素
shift 取出数组的开始位置的一个元素,整个数组发生变化(前移).
pop 从数组末端取出一个元素.返回删除的那个元素
splice 删除数组某一位置的元素
concat 数组拼接,不会改变元素组,返回值是拼接后的数组
split 将字符串分割成数组.返回的是删除元素组成的数组
join 将数组元素拼接成字符串
函数
函数的格式:
//注意这里的形参不带类型(不同于其他的编程语言)
function 函数名(形参){
函数体
}
函数的调用: 函数名(实参);
匿名函数的创建方式
var 变量 = function(形参){
函数体
}
调用: 变量(实参);
//立即执行函数,在函数后面直接加()
函数的返回值:
1.并不是所有的函数都有返回值
2.当没有定义返回值时,默认返回undefined(不同于其他语言返回void)
3.函数的返回值用return返回,函数遇到return就立即结束执行
4.return后面什么都不跟,代表退出函数,返回的是undefiend
5.返回值只有一个
对象
对象的作用:封装信息
//key加不加引号都可以,建议不加,如果要使用一些特殊的名字必须得加
var user= {
"name":"zhangsan",
"age":14,
"sex":"男",
}
js中的对象分类
1.内置对象,由es标准定义的对象,如Math
2.宿主对象浏览器环境提供的对象,如consloe,document
3.自定义对象,开发人员自定义的对象
创建对象的方式
1.字面量方式的创建
var user= {
"name":"zhangsan",
"age":14,
"sex":"男",
}
2.new Object() new出来一个对象
给对象添加新属性:
对象.属性名 = 属性值;
user.height = 175;
获取对象的属性:
对象.属性名
删除对象的属性delete
delete user.name //把user里面的name属性删除
注意:获取对象没有的属性是不会报错的,会返回undefined
对象的遍历 for in:
<!--for in专门用来遍历对象-->
for(var key in user){
<!--key就是循环对象的没一个属性名-->
通过key获取对应的属性值
注意:如果直接用user.key则打印出的事undefined,因为key是变量.因为点语法会把后边的当做字符串处理
这里要用user[key]取对应的vlue值
[]语法会把对应的key变量的值解析出来(name,age...),然后去user里面取值
}
arguments 函数实参对象
只能在函数中使用,类数组的形式
function add(x, y){
//函数内部自带一个arguments,保存了这个函数调用时的所有实参信息
console.log(arguments);//输出[10, 20, callee: f, Symbol(Symbol.iterator): f] 类数组/伪数组
//具体数组的形式,有长度属性,有索引,但不具备数组的方法:pop/ shift...等
return x+y;
}
add(10,20);
this的指向
this在js中,表示一个指针
大多数情况下,this指向调用者(.前面的对象)
我们声明的全局变量和全局方法都会作为window的一条属性和方法
特殊情况:在构造函数中,this指向new出来的对象(实例对象)
构造函数
//创造一个构造函数
function Student(name, age){
this.name = name;
this.age = age;
this.school = "江苏省第一初级中学";
this.subject = "编程";
}
var s1 = Student("小明",18);
//s1就是实例对象
Json对象
//注意:网络间无法传输数组和对象这些数据类型的,可以传输字符串
var user= {
name: "zhangsan",
age:18
}
//把对象转化为josn字符串
JSON.stringify(user) // '{"name":"zhangsan","age":18}' 这是json字符串
//普通的字符串 '{name:"zhangsan",age:18}'
JSON.parse(json字符串) 会把json字符串转化为对象,如果是普通的字符串,则会报错
forEach遍历
for of也可以用来对数组遍历,但用不多,因为拿不到下标
forEach(),也可以实现对数组的遍历
使用时,需要传递一个函数进去
函数作为一个参数时,我们叫这个函数为回调函数
var arr= ["张三",,"李四","王五"];
//这个传进去的函数有三个参数,第一个是遍历出的元素,第二个参数是索引,第三个是数组本身
arr.forEach(function(item, index, arr){
});
变量作用域链
变量的作用域作用域分为全局作用域和局部作用域(函数内部作用域)
当一个变量被使用时,先在自身的作用域查找,如果找不到就向自身的上一级作用域查,一层一层的查找,直到查找到全局作用域,如果还没找到就说明没有这个变量.
如果在这个期间找到了,就会拿来用,不再向上查找
声明的提升和预解析
执行js代码之前,有一个预解析阶段,会将所用var声明的变量提升到该作用域的最顶端
注意:这里提升的仅仅是声明动作,赋值动作不提升.特别注意提升的作用域是原始对应的作用域,并非都是全局作用域
consloe.log(a); //输出undefined
var a = 100;
解读:上面的代码可以解读为
var a;
consloe.log(a); //只声明,没赋值,所以就输出了undefined
a = 100;
对于function声明的函数,在js代码执行之前,预解析阶段会把function声明的函数提升到该作用域的最顶端
say(); //不报错,输出hello
function say(){
consloe.log("hello");
}
特殊情况:匿名函数
eat(); //报错,提示eat is not a function
var eat = function(){
console.log("吃");
}
匿名函数可以这么理解,var eat提升的仅仅是变量eat的名字,此时eat并没有赋值成函数,所以那样调用就出现问题了
*不带var声明的变量,默认是全局变量,即使是在函数中声明的.但是在严格模式下会报错
递归
function foo(n){
if(n > 0){
consloe.log(n);
n--;
foo(n);
}
}
//以上就是一个递归,自己再调用自己
//要注意的是:要想停下来,必须写停止条件,不然就会形成无限递归,造成栈溢出的错误
对象的克隆
笨办法就是for in循环对象,把对象的每个属性和值,添加到一个新的空白对象中去.但这种也只是浅克隆.因为这样只能克隆对象只包含一层属性的情况,如果对象里面嵌套对象,通过这种克隆的,如果改变里面对象的值,还是会修改到最初的对象.
如果把对象里面所有的都克隆就叫做深拷贝,目前js没有提供这种方法,只能通过库实现
浅克隆:我们可以使用 Object.assign({},要克隆的对象)来实现
网友评论