js 的 入门

js是解释型,弱类型语言

  • js 的特点:

    1. 简单 :因为是 弱类型语言,使用一个var关键字声明所有的变量
    2. 动态性 : 实现页面的特效和交互
    3. 跨平台 : 运行于浏览器的脚本语言,只要系统有浏览器,并且浏览器支持运行js即可
    4. 不依赖于服务器: 不同于服务器端的语言(php, java);在客户端运行
  • js 的作用:

    1. 和页面进行交互; 操作DOM
    2. 和浏览器进行交互; 操作BOM
    3. 发送请求 ; ajax
    4. 搭建后台(nodejs)

js的引入方式

  1. 外链式: 引入外部的js文件, 文件的扩展名是 .js ; 通过script的src属性引入
  1. <script src='url'></script>
  1. 内嵌式: 直接在当前的页面中引入js; 通过script直接引入
  1. <script>
  2. // js代码
  3. </script>
  1. 行内引入: 直接在html标签内引入js代码
  1. <h1 onclick="alert(123)">hello world</h1>

js代码可以放到页面的任何地方。但是位置不同,页面渲染效果不同, 因此我们一般把js代码放到head标签中 或者 是 body结束标签之前的位置(推荐位置)

js 的变量

js 的语句是一条指令,指令是告诉浏览器要执行的操作
js 是区分大小的

  • 变量的命名

    1. 使用字母, , $ 作为开头,后边可以是字母, 数字, , $ 的组合
    2. 使用驼峰命名法, 匈牙利命名法, 帕斯卡命名法
    3. 不能使用关键字或者保留字
    4. 变量名是区分大小
    5. 变量名尽量有意义
  • 变量的声明方式

    1. 使用一个关键字var 声明所有的变量
    2. 变量必须先声明后使用
    3. 三种方式声明变量

      • 先声明, 后赋值

        1. var a;
        2. a = 100;
      • 声明的同时并赋值

        1. var num = 200
      • 可以使用一个var声明多个变量, 多个变量之间使用逗号隔开; 变量的数据类型不受限制

        1. var a = 100,
        2. b = 200,
        3. sum ,
        4. flag = true;
        5. sum = a + b

js 的数据类型

  1. 基本数据类型

    • Undefined : 只有一个特殊的值 undefined; 含义是变量声明了但是未初始化, 变量的默认值是 undefined

    • null : 尚未存在的对象

    • Number :数值类型

      1. 整型
      2. 浮点型
      3. 存在特殊的值

        • 有穷和无穷: 判断一个数是否有穷, 通过 isFinite() 方法判断, 结果是布尔值, true : 有穷; false: 无穷
        • 非数值 NaN : 判断一个值/变量 是否是非数值; 通过 isNaN() 方法判断, 结果是布尔值, true:非数值; false: 是数值 ; NaN 自身不相等
      4. 计数方式

        • 八进制 : 以0作为前缀表示八进制; 底数: 0 - 7
        • 十进制 :
        • 十六进制: 以 0x 作为前缀; 底数: 0- 9; a(10) - f(15)
        • 科学计数法: 1.03e+10/ 1.03e-10/
    • String : 字符串类型; 存储的是文本数据

      1. 使用单双引号定义字符串类型
      2. 引号都是成对出现的
      3. 单双引号可以嵌套的,但是如果单双引号自身嵌套,需要使用转义字符\ 进行转义 ; ‘ “
    • Boolean: 布尔类型; 只有两个值: true false

      1. 可以转换为false的6种假值: 0 ‘’ undefined null NaN false
  2. 引用数据类型

    • 数组
    • 对象

js 的数据类型转换

  1. 转换为字符串 toString() : 任何数据都可以转换为字符串类型, 但是 不能转换null 和 undefined,
  1. var num = 100;
  2. var res = num.toString();

toString()的基模式转换了解即可

  1. 转换为整型: parseInt()
  1. var str = '100元'
  2. var res = parseInt(str);
  1. 转换为浮点型: parseFloat()
  1. var str = '100.99元'
  2. var res = parseFloat(str);

parseInt()和 parseFloat() 逐位进行转换; 首先判断第一位是否是有效数字;如果是则继续向后判断,直到遇到一个非有效数数字停止转换,。此时会把前边转换的结果作为一个整体返回; 如果不是则直接放回结果NaN; 两者的区别是 parseFloat()可以识别第一个小数点

  1. 强制类型转换:
  • Boolean() : 强制转换为布尔类型 6 个假值
  1. 数值类型的 0 ===》 false ; 1 ===》 true
  2. 空字符串: ‘’ ===> false
  • Number() : 强制转换为数值类型, 整体进行转换
  1. true ===> 1 ; false ===> 0
  2. ‘’ ===> 0
  3. null ==》0
  4. undefined ===》 NaN
  • String() : 强制转换为字符串类型; 可以转换null 和 undefined,

运算符

  1. 算术运算符 : + - * / %

    • 自增自减:

      • 前增 / 前减: 首先自身先去改变(+1 / -1); 然后拿着改变后的值参与运算
      • 后曾 / 后减: 首先拿着之前的值参与运算, 然后自身在去改变(+1 / -1)
      • 两种用法 求和和拼接(字符串拼接)
        • / % : 存在隐式类型转换(字符串类型的数值字面量)
  2. 关系运算符 : > >= < <= == === != !==

    • == 和 === 区别:== 相等, 判断值相等,不判断数据类型; === 全等, 判断值和数据类型都相等则相等
    • 关系运算的结果是布尔值
  3. 逻辑运算符 : && || !

    • && : 两边都为真则结果为真,一边为假则结果假; 存在短路情况的: 如果 && 左边为假,则直接返回结果为假,后边不在考虑
    • || : 两边只要一边为真则结果为真; 两边都为假则结果假; 存在短路情况, 如果 || 左边为真,则直接返回结果为真, 后边不在考虑
    • ! : 真假互换, 6 种假值
    • 逻辑运算符的结果是布尔值或者是具体的值(一般都是用于条件语句中,具体的值会经过隐式类型转换变为true或者false)
  4. 组合运算符 : += -= *= /= %=
  1. var num = 10;
  2. // 全写形式
  3. num = num + 50;
  4. // 简写形式
  5. num += 50;
  1. 条件运算符 : ?:
  1. // ? 前边是一个表达式; 判断表达式是否成立,如果成立,执行?后边的代码; 如果不成立,执行 : 后边的代码
  2. var num = 3 > 2 ? 100 : 500;
  • 条件运算符可以嵌套
  1. // ? 前边是一个表达式; 判断表达式是否成立,如果成立,执行?后边的代码; 如果不成立,执行 : 后边的代码
  2. var n = 10;
  3. var num = n > 2 ? 100 : n < 20 ? 300 : 500;
  1. 运算符的优先级 : () > 算数运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符

js 的语句

  1. if语句
  1. if(条件){}
  2. if(条件){}else{}
  3. // 了解运行机制
  4. if(条件1){}else if(条件2){}else if(条件3){}else{}
  1. switch语句
  1. // 表达式: 经过计算得到一个具体的值, 形如 parseInt(score / 10); 也可以是一个具体的值 n
  2. switch(表达式){
  3. // case 后边也会是一个具体的值, 是switch语句中表达式的结果之一
  4. case val1:代码1
  5. break
  6. case val2: 代码2
  7. break
  8. default:
  9. 代码3
  10. }
  1. var a = prompt('请输入一个数字'); // 2
  2. var b = prompt('请输入运算符方式 + - * / %'); // +
  3. var c = prompt('请输入一个数字'); // 3
  4. var res = 0;
  5. a = parseFloat(a)
  6. c = parseFloat(c)
  7. switch(b){
  8. case "+": res = a + c;
  9. break;
  10. case "-": res = a - c;
  11. break;
  12. case "*" : res = a * c;
  13. break;
  14. case "/" : res = a / c;
  15. break;
  16. case '%' :res = a % c;
  17. break;
  18. default:
  19. alert('提示')
  20. }
  1. 循环语句

    1. while循环

      1. // 先判断后执行 : 条件不满足,循环体可能一次都不执行
      2. while(条件){
      3. // 循环体
      4. // 循环的控制
      5. }
    2. do-while循环

      1. // 先执行后判断; 不管条件是否满足,循环体至少被执行一次
      2. do{
      3. // 循环体
      4. // 循环的控制
      5. }while(条件)
    3. 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++){

  1. }

}


<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);
    
  1. 函数的参数

    • 形参 : 函数声明时传入的参数称之为形参, 形参就相当于函数内声明的变量, 可以在函数内直接使用
    • 实参 : 函数调用时传入的参数称之为实参,实参就是给形参赋值
    • 形参和实参的关系:

      • 形参多 实参少: 多余的形参默认值是undefined
      • 形参少 实参多: 多余的实参会被忽略
      • 形参和实参是一一对应的
  2. 函数的返回值 : 使用return语句作为函数的返回值;
function fun(){
    // return 语句后边的value就是函数的返回值, 返回值可以是任意类型
    return value;
}
fun()

// 函数作为返回值
function fun(){
    return function(){
        console.log('返回值');
    }
}
// var res = fun();
// res()
//  函数作为返回值
fun()();
  1. 变量的作用域

    1. 全局作用域

      • 函数外声明的变量拥有全局作用域
      • window对象的属性和方法拥有全局作用域
      • 最外层函数内声明的变量,在这个函数体内拥有全局作用域
      • 不使用var关键字声明的变量拥有全局作用域
    2. 局部作用域

      • 在函数内声明的变量拥有局部作用域
  2. 变量的提升机制

js 对象

js万物皆对象; 只有对象才拥有属性和方法

  1. js 对象的声明方式
// 属性名自定义
var person = new Object();
person.name = '小明';
person.age = 18;
person.say = function(){
    console.log('ok')
}

//   对象中的属性和属性值是以键值对形式存在
var obj = {
    name:'tom',
    age:18,
    say:function(){

    }
}
  1. 对象取值 :
// 对象.属性名
 var name = person.name
//   对象['属性名']
var age = person['age']
  1. 修改对象的属性值 : 重新赋值
// 对象.属性名
person.name = 'tom';
//   对象['属性名']
person['age'] = 100;
  1. 调用对象的方法 : 函数作为值赋值给对象的属性,则称之为对象的方法(本质还是函数)
person.say();
person['say']()
  1. 遍历对象for-in语句
// obj 就是要遍历的对象
for(var key in obj){
    // key 代表对象的属性
    // 获取属性值 obj[key] 
}
  1. 对象中两种取值方式的区别 . [] 区别
  • 语法结构: 对象.属性名 ; . 右边是一个具体的属性名,不能识别变量
  • 语法结构: 对象[‘属性名’] ; [] 里边是一个字符串类型的属性名; 可以识别变量(变量永远不要添加引号)

字符串对象

字符串是用来存储文本数据信息

  1. 字符串对象的属性: length 获取字符串的长度

字符串对象的方法:

  1. str.charAt(index) : 获取指定索引值位置的字符 参数是索引值; 索引值是从0开始的
  2. str.concat(str1, str2,…) : 拼接字符串, 参数就是要拼接的字符串,参数的个数不受限制的
  3. str.indexOf(params) : 检索指定字符在字符串中第一次出现位置的索引值; 如果存在则返回对应的索引值,如果不存在,则返回 -1;
  4. str.lastIndexOf(params) : 检索指定字符在字符串中最后一次出现位置的索引值; 如果存在则返回对应的索引值,如果不存在,则返回 -1;

    • 延伸1 : 可以判断字符串中是否存在某个字符 indexOf() lastIndexOf()
    • 延伸2 : 可以判断字符在字符串中是否只出现了一次 ; 第一次出现位置的索引值 indexOf() 和最后一次出现位置的索引值 lastIndexOf()是 相等的
  5. 字符串中和正则相关的方法

    • str.match(正则) : 找到一个或多个于正则表达式匹配的结果
    • str.replace(正则, 替换的字符串) :替换与正则表达式相匹配的字符
    • str.search(正则) : 返回的是和正则表达式匹配的字符所在的索引值
  6. 字符串的分割

    • str.substring(startIndex, endIndex) : 从起点索引值位置开始截取字符串, 到指定的终点位置结束; startIndex起点索引值 endIndex 终点索引值(可选项) ;截取特点是包前不包后 ; 不能接受负数为参数
    • str.slice(startIndex, endIndex) : 从起点索引值位置开始截取字符串, 到指定的终点位置结束;startIndex起点索引值 endIndex 终点索引值(可选项) ;截取特点是包前不包后 ; 可以接受负数为参数; 意味着倒着截取
    • str.substr(startIndex, length) : 从起点索引值位置开始截取指定长度的字符串
  7. 字符串分割为字符串数组

    • str.split() : 无参数; 整个字符串分割为一个数组
    • str.split(‘’): 参数是空字符串, 逐位分割字符串为字符串数组
    • str.split(params): params 参数是具体的字符 ; 以参数作为分割的标志,分割后的字符串数组不包含参数

数组对象

数组是通过下标取值, 索引值 从 0 开始的

  1. 数组的属性: 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)

数组的遍历

  1. 使用for循环 遍历数组 for() for-in语句
  2. 使用forEach() 方法遍历数组
var arr = [1, 2,3,4];
arr.forEach(function(item, index){
//  item 是数组中的每个值
//  index 是数组的下标
})

数组相关的算法

  1. 数组的去重的算法: 至少掌握两种
//  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);
        }
    }
}
  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)
}