js 的 入门
js是解释型,弱类型语言
js 的特点:
- 简单 :因为是 弱类型语言,使用一个var关键字声明所有的变量
- 动态性 : 实现页面的特效和交互
- 跨平台 : 运行于浏览器的脚本语言,只要系统有浏览器,并且浏览器支持运行js即可
- 不依赖于服务器: 不同于服务器端的语言(php, java);在客户端运行
js 的作用:
- 和页面进行交互; 操作DOM
- 和浏览器进行交互; 操作BOM
- 发送请求 ; ajax
- 搭建后台(nodejs)
js的引入方式
- 外链式: 引入外部的js文件, 文件的扩展名是 .js ; 通过script的src属性引入
<script src='url'></script>
- 内嵌式: 直接在当前的页面中引入js; 通过script直接引入
<script>
// js代码
</script>
- 行内引入: 直接在html标签内引入js代码
<h1 onclick="alert(123)">hello world</h1>
js代码可以放到页面的任何地方。但是位置不同,页面渲染效果不同, 因此我们一般把js代码放到head标签中 或者 是 body结束标签之前的位置(推荐位置)
js 的变量
js 的语句是一条指令,指令是告诉浏览器要执行的操作
js 是区分大小的
变量的命名
- 使用字母, , $ 作为开头,后边可以是字母, 数字, , $ 的组合
- 使用驼峰命名法, 匈牙利命名法, 帕斯卡命名法
- 不能使用关键字或者保留字
- 变量名是区分大小
- 变量名尽量有意义
变量的声明方式
- 使用一个关键字var 声明所有的变量
- 变量必须先声明后使用
三种方式声明变量
先声明, 后赋值
var a;
a = 100;
声明的同时并赋值
var num = 200
可以使用一个var声明多个变量, 多个变量之间使用逗号隔开; 变量的数据类型不受限制
var a = 100,
b = 200,
sum ,
flag = true;
sum = a + b
js 的数据类型
基本数据类型
Undefined : 只有一个特殊的值 undefined; 含义是变量声明了但是未初始化, 变量的默认值是 undefined
null : 尚未存在的对象
Number :数值类型
- 整型
- 浮点型
存在特殊的值
- 有穷和无穷: 判断一个数是否有穷, 通过 isFinite() 方法判断, 结果是布尔值, true : 有穷; false: 无穷
- 非数值 NaN : 判断一个值/变量 是否是非数值; 通过 isNaN() 方法判断, 结果是布尔值, true:非数值; false: 是数值 ; NaN 自身不相等
计数方式
- 八进制 : 以0作为前缀表示八进制; 底数: 0 - 7
- 十进制 :
- 十六进制: 以 0x 作为前缀; 底数: 0- 9; a(10) - f(15)
- 科学计数法: 1.03e+10/ 1.03e-10/
String : 字符串类型; 存储的是文本数据
- 使用单双引号定义字符串类型
- 引号都是成对出现的
- 单双引号可以嵌套的,但是如果单双引号自身嵌套,需要使用转义字符\ 进行转义 ; ‘ “
Boolean: 布尔类型; 只有两个值: true false
- 可以转换为false的6种假值: 0 ‘’ undefined null NaN false
引用数据类型
- 数组
- 对象
js 的数据类型转换
- 转换为字符串 toString() : 任何数据都可以转换为字符串类型, 但是 不能转换null 和 undefined,
var num = 100;
var res = num.toString();
toString()的基模式转换了解即可
- 转换为整型: parseInt()
var str = '100元'
var res = parseInt(str);
- 转换为浮点型: parseFloat()
var str = '100.99元'
var res = parseFloat(str);
parseInt()和 parseFloat() 逐位进行转换; 首先判断第一位是否是有效数字;如果是则继续向后判断,直到遇到一个非有效数数字停止转换,。此时会把前边转换的结果作为一个整体返回; 如果不是则直接放回结果NaN; 两者的区别是 parseFloat()可以识别第一个小数点
- 强制类型转换:
- Boolean() : 强制转换为布尔类型 6 个假值
- 数值类型的 0 ===》 false ; 1 ===》 true
- 空字符串: ‘’ ===> false
- Number() : 强制转换为数值类型, 整体进行转换
- true ===> 1 ; false ===> 0
- ‘’ ===> 0
- null ==》0
- undefined ===》 NaN
- String() : 强制转换为字符串类型; 可以转换null 和 undefined,
运算符
算术运算符 : + - * / %
自增自减:
- 前增 / 前减: 首先自身先去改变(+1 / -1); 然后拿着改变后的值参与运算
- 后曾 / 后减: 首先拿着之前的值参与运算, 然后自身在去改变(+1 / -1)
- 两种用法 求和和拼接(字符串拼接)
- / % : 存在隐式类型转换(字符串类型的数值字面量)
关系运算符 : > >= < <= == === != !==
- == 和 === 区别:== 相等, 判断值相等,不判断数据类型; === 全等, 判断值和数据类型都相等则相等
- 关系运算的结果是布尔值
逻辑运算符 : && || !
- && : 两边都为真则结果为真,一边为假则结果假; 存在短路情况的: 如果 && 左边为假,则直接返回结果为假,后边不在考虑
- || : 两边只要一边为真则结果为真; 两边都为假则结果假; 存在短路情况, 如果 || 左边为真,则直接返回结果为真, 后边不在考虑
- ! : 真假互换, 6 种假值
- 逻辑运算符的结果是布尔值或者是具体的值(一般都是用于条件语句中,具体的值会经过隐式类型转换变为true或者false)
- 组合运算符 : += -= *= /= %=
var num = 10;
// 全写形式
num = num + 50;
// 简写形式
num += 50;
- 条件运算符 : ?:
// ? 前边是一个表达式; 判断表达式是否成立,如果成立,执行?后边的代码; 如果不成立,执行 : 后边的代码
var num = 3 > 2 ? 100 : 500;
- 条件运算符可以嵌套
// ? 前边是一个表达式; 判断表达式是否成立,如果成立,执行?后边的代码; 如果不成立,执行 : 后边的代码
var n = 10;
var num = n > 2 ? 100 : n < 20 ? 300 : 500;
- 运算符的优先级 : () > 算数运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符
js 的语句
- if语句
if(条件){}
if(条件){}else{}
// 了解运行机制
if(条件1){}else if(条件2){}else if(条件3){}else{}
- switch语句
// 表达式: 经过计算得到一个具体的值, 形如 parseInt(score / 10); 也可以是一个具体的值 n
switch(表达式){
// case 后边也会是一个具体的值, 是switch语句中表达式的结果之一
case val1:代码1
break
case val2: 代码2
break
default:
代码3
}
var a = prompt('请输入一个数字'); // 2
var b = prompt('请输入运算符方式 + - * / %'); // +
var c = prompt('请输入一个数字'); // 3
var res = 0;
a = parseFloat(a)
c = parseFloat(c)
switch(b){
case "+": res = a + c;
break;
case "-": res = a - c;
break;
case "*" : res = a * c;
break;
case "/" : res = a / c;
break;
case '%' :res = a % c;
break;
default:
alert('提示')
}
循环语句
while循环
// 先判断后执行 : 条件不满足,循环体可能一次都不执行
while(条件){
// 循环体
// 循环的控制
}
do-while循环
// 先执行后判断; 不管条件是否满足,循环体至少被执行一次
do{
// 循环体
// 循环的控制
}while(条件)
for循环 ```javascript for(var i = 0; i < 5; i++){ // 循环体 console.log(i) }
// for循环的嵌套 for(var i = 0; i < 3; i++){ for(var j = 0; j < 3; j++){
}
}
<a name="1e5f8d92"></a>
### js 的函数
1.
函数的声明方式
- 使用关键字声明函数function
```javascript
function 函数名(){
}
// 调用函数
函数名();
函数表达式声明函数
var 变量 = function(){ // 把一个匿名函数赋值给一个变量 } // 变量名就是函数名 变量名()
调用函数 都是通过函数名进行调用; 函数必须被调用才能执行
- 可以把函数作为值赋值给一个变量; 使用函数名进行赋值, 不能使用函数调用; 此时变量名就相当于函数的别名;可以调用执行函数
function fun(){ console.log(1); } // 函数调用 // fun(); // 可以把函数作为值赋值给一个变量 使用函数名进行赋值 // var f = fun; // console.log(f); // f() // f 就是函数的别名, 可以调用函数 // 把函数调用赋值给一个变量; 实际是吧函数的返回值赋值给变量f var f = fun(); console.log(f);
函数的参数
- 形参 : 函数声明时传入的参数称之为形参, 形参就相当于函数内声明的变量, 可以在函数内直接使用
- 实参 : 函数调用时传入的参数称之为实参,实参就是给形参赋值
形参和实参的关系:
- 形参多 实参少: 多余的形参默认值是undefined
- 形参少 实参多: 多余的实参会被忽略
- 形参和实参是一一对应的
- 函数的返回值 : 使用return语句作为函数的返回值;
function fun(){
// return 语句后边的value就是函数的返回值, 返回值可以是任意类型
return value;
}
fun()
// 函数作为返回值
function fun(){
return function(){
console.log('返回值');
}
}
// var res = fun();
// res()
// 函数作为返回值
fun()();
变量的作用域
全局作用域
- 函数外声明的变量拥有全局作用域
- window对象的属性和方法拥有全局作用域
- 最外层函数内声明的变量,在这个函数体内拥有全局作用域
- 不使用var关键字声明的变量拥有全局作用域
局部作用域
- 在函数内声明的变量拥有局部作用域
- 变量的提升机制
js 对象
js万物皆对象; 只有对象才拥有属性和方法
- js 对象的声明方式
// 属性名自定义
var person = new Object();
person.name = '小明';
person.age = 18;
person.say = function(){
console.log('ok')
}
// 对象中的属性和属性值是以键值对形式存在
var obj = {
name:'tom',
age:18,
say:function(){
}
}
- 对象取值 :
// 对象.属性名
var name = person.name
// 对象['属性名']
var age = person['age']
- 修改对象的属性值 : 重新赋值
// 对象.属性名
person.name = 'tom';
// 对象['属性名']
person['age'] = 100;
- 调用对象的方法 : 函数作为值赋值给对象的属性,则称之为对象的方法(本质还是函数)
person.say();
person['say']()
- 遍历对象for-in语句
// obj 就是要遍历的对象
for(var key in obj){
// key 代表对象的属性
// 获取属性值 obj[key]
}
- 对象中两种取值方式的区别 . [] 区别
- 语法结构: 对象.属性名 ; . 右边是一个具体的属性名,不能识别变量
- 语法结构: 对象[‘属性名’] ; [] 里边是一个字符串类型的属性名; 可以识别变量(变量永远不要添加引号)
字符串对象
字符串是用来存储文本数据信息
- 字符串对象的属性: length 获取字符串的长度
字符串对象的方法:
- str.charAt(index) : 获取指定索引值位置的字符 参数是索引值; 索引值是从0开始的
- str.concat(str1, str2,…) : 拼接字符串, 参数就是要拼接的字符串,参数的个数不受限制的
- str.indexOf(params) : 检索指定字符在字符串中第一次出现位置的索引值; 如果存在则返回对应的索引值,如果不存在,则返回 -1;
str.lastIndexOf(params) : 检索指定字符在字符串中最后一次出现位置的索引值; 如果存在则返回对应的索引值,如果不存在,则返回 -1;
- 延伸1 : 可以判断字符串中是否存在某个字符 indexOf() lastIndexOf()
- 延伸2 : 可以判断字符在字符串中是否只出现了一次 ; 第一次出现位置的索引值 indexOf() 和最后一次出现位置的索引值 lastIndexOf()是 相等的
字符串中和正则相关的方法
- str.match(正则) : 找到一个或多个于正则表达式匹配的结果
- str.replace(正则, 替换的字符串) :替换与正则表达式相匹配的字符
- str.search(正则) : 返回的是和正则表达式匹配的字符所在的索引值
字符串的分割
- str.substring(startIndex, endIndex) : 从起点索引值位置开始截取字符串, 到指定的终点位置结束; startIndex起点索引值 endIndex 终点索引值(可选项) ;截取特点是包前不包后 ; 不能接受负数为参数
- str.slice(startIndex, endIndex) : 从起点索引值位置开始截取字符串, 到指定的终点位置结束;startIndex起点索引值 endIndex 终点索引值(可选项) ;截取特点是包前不包后 ; 可以接受负数为参数; 意味着倒着截取
- str.substr(startIndex, length) : 从起点索引值位置开始截取指定长度的字符串
字符串分割为字符串数组
- str.split() : 无参数; 整个字符串分割为一个数组
- str.split(‘’): 参数是空字符串, 逐位分割字符串为字符串数组
- str.split(params): params 参数是具体的字符 ; 以参数作为分割的标志,分割后的字符串数组不包含参数
数组对象
数组是通过下标取值, 索引值 从 0 开始的
- 数组的属性: length 获取数组的长度
数组对象的方法
// 数组的拼接 concat(params) 参数个数不受限制 返回的是拼接后的新数组,对原数组无影响
var res = arr.concat(params)
// 数组的检索
// 1 检索指定的值在数组中第一次出现位置的索引值, 如果不存在则为 -1
var index = arr.indexOf(value);
// 2 检索指定的值在数组中最后一次出现位置的索引值, 如果不存在则为 -1
var index = arr.lastIndexOf(value);
// 数组中添加元素
arr.push(value1, value2,...) // 在数组的末尾增加一个或多个元素,并返回数组的新长度。
arr.unshift(value1, value2,...) // 在数组的开头增加一个或多个元素,并返回数组的新长度。
// 数组中删除元素
arr.pop() // 删除数组的最后一个元素,并返回删除的这个元素。
arr.shift() // 删除数组的第一个元素,并返回删除的这个元素。
// 数组转换为字符串
arr.toString() // 数组转换为字符串
arr.join(params) // 连接所有数组元素组成一个字符串。 参数就是拼接符,替换数组中的逗号
// 数组的反转
arr.reverse()
// 数组的排序
arr.sort(function(a,b){ return a - b})
// 数组的截取 接受负数为参数,意味着倒着截取数组
arr.slice(startIndex, endIndex)
// 数组的删除替换 从指定的startIndex 索引值位置开始删除指定长度 length 的元素,替换为 value指定的值
arr.splice(startIndex, length, value)
数组的遍历
- 使用for循环 遍历数组 for() for-in语句
- 使用forEach() 方法遍历数组
var arr = [1, 2,3,4];
arr.forEach(function(item, index){
// item 是数组中的每个值
// index 是数组的下标
})
数组相关的算法
- 数组的去重的算法: 至少掌握两种
// 1 数组去重 第一次出现位置和最后一次出现位置
for(var i = 0; i < arr.length; i++){
if(arr.indexOf(arr[i]) != arr.lastIndexOf(arr[i])){
arr.splice(i, 1);
i--;
}
}
// 2 去重 新数组判断值是否存在
var res = [];
for(var i = 0; i < arr.length; i++){
if(res.indexOf(arr[i]) == -1){
res.push(arr[i])
}
}
// 3 去重 逐位比较删除
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++){
if(arr[i] == arr[j]){
arr.splice(j, 1);
j--;
}
}
}
// 4 去重 逐位比较删除
for(var i = arr.length - 1; i >= 0; i--){
for(var j = i - 1; j >= 0; j--){
if(arr[i] == arr[j]){
arr.splice(j, 1);
}
}
}
- 数组的排序
arr.sort(function(a,b){
return a-b
})
// 冒泡排序
var temp;
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++){
if(arr[i] > arr[j]){
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
Math 对象
// 向上取整
Math.ceil(value)
// 向下取整
Math.floor(value)
// 四舍五入
Math.round(value)
// 随机数 范围 [0, 1)
Math.random()
// 最大值 最小值
Math.max(value, ...)
Math.min(value, ...)
// 幂运算
Math.pow(x,y)
var res = x ** y ;
// 绝对值
Math.abs(value)
// 圆周率
var r = Math.PI
随机数函数封装 任意范围内的随机整数
function random(a,b){
return Math.floor( Math.random() * (b - a + 1) + a)
}
日期对象 Date
掌握倒计时
var d = new Date();
// 获取日期和时间
d.getFullYear(); // 年份是四位数
d.getMonth() ; // 月份范围0 - 11
d.getDate() ; // 获取一个月中的某一天
d.getDay() ; // 获取一周中的某一天
d.getHours() // 时
d.getMinutes(); // 分
d.getSeconds(); //秒
d.getTime() ;// 获取毫秒数 相对于1970.1.1 至今的毫秒数
// 设置日期和时间
d.setFullYear(value); // 年份是四位数
d.setMonthvalue() ; // 月份范围0 - 11
d.setDate(value) ; // 获取一个月中的某一天
d.setHours(value) // 时
d.setMinutes(value); // 分
d.setSeconds(value); //秒
d.setTime(value) ;// 获取毫秒数 相对于1970.1.1 至今的毫秒数
// 综合设置 如果设置的时间超过指定的值,会自动过渡到下一天或者下个月 或者下一年
var date = new Date(value) // 设置毫秒数
var date = new Date(year, month, day) // 设置毫秒数
var date = new Date(year, month, day, hour, min, sec) // 设置毫秒数
var date = new Date('year-month-day h:m:s') // 设置毫秒数
计时器
setInterval() : 每间隔指定的时间执行一次,反复执行
// 计时器有默认时间的
var timer = setInterval(function(){
}, time)
// 可以把函数独立出来, 使用函数名
function count(){}
var timer = setInterval(count, time)
setTimeout() : 间隔指定的时间执行一次代码
// 计时器有默认时间的
var timer = setTimeout(function(){
}, time)
// 可以把函数独立出来, 使用函数名
function count(){}
var timer = setTimeout(count, time)
计时器和for循环面试题
// 1s以后直接打印 三个3
for(var i = 0; i < 3; i++){
setTimeout(function(){
console.log(i);
}, 1000)
}
// 每间隔1s打印一个3
for(var i = 0; i < 3; i++){
setTimeout(function(){
console.log(i);
}, i * 1000)
}
// 间隔1s输出 0 1 2
for(var i = 0; i < 3; i++){
// 闭包 本质函数 自执行函数
(function(i){
setTimeout(function(){
console.log(i);
}, i * 1000)
})(i)
}