js基础

130 阅读8分钟

运算符

  • typeof: typeof null(object)
  • parseInt
  • parseFloat
  • false的值 :false,0,null,undefined,''

parseInt(11.33) //11
parseInt(11.93) //11
parseInt('11.48') //11
parseInt('11.48aaa') //11
parseInt('11aa.48aaa') //11
parseInt('aa11aa.48aaa') //NaN

var num = 8
num++ // 8
num // 9
++num // 10
num // 10
num--  // 10
num  //9 
--num // 8
num //8

// 逻辑判断特殊值
console.log(true && 'helllo') // hello
console.log(false || 'default') // 'default'
console.log(false && 'not print') // false
console.log(true || 'not print') // true
console.log(4 || 'not print') // 4
console.log(!4, !!4) // false true

//位运算符 》 转换为二进制再计算 5: 101,3:011
console.log(5 & 3) //1  (001 每位&&)
console.log(5 | 3) //7  (111 每位||)
console.log(5 ^ 3) //6 (110 不同返回1,相同返回0)
console.log(~5) // -6 (-(当前数+1))
console.log(5>>1) // 2 (右移1位)
console.log(5<<2) // 20 (左移2位)

流程控制

  • break 结束当前循环
  • continue 跳出本次循环,该语句后面的代码不再执行,整个循环体继续循环。
if(){
}else{
}

if(){
}else if(){
}else{
}

switch(变量){
    case 1:
        如果变量和1的值相同,执行该处代码
    break;

    case 2:
        如果变量和2的值相同,执行该处代码
    break
    default:
        如果变量和以上的值都不相同,执行该处代码
    break;
}

while(条件表达式){
       只要条件表达式结果为true,循环一直执行,当条件表达式结果为false的时候,循环终止
}

do{
     循环体代码;首先执行该循环体代码一次。如果while后边的表达式结果为true,该循环体会一直循环。如果结果false,该循环终止。
}while(条件表达式)

//do  while 比while循环多循环一次。

for(定义变量;条件表达式;自增/自减){
    循环体代码
}

// for..in多用于对象的遍历(也可用于循环数组)
for(var  key  in  obj){    console.log(key+':'+obj[key]);    }

//for...of多用于数组的遍历
//这里的索引index从1开始;数组中的索引从0开始

数组

  • 传单个值时new Array 和array中参数代表数组的长度
  • stack栈:后进先出 Array.push(), Array.pop()
  • queue队列模式:先进先出Array.shift()
//创建数组
var a = [1,2,3]  //[1, 2, 3]
var b = new Array(1,2,3) //[1, 2, 3]
var c = Array(1,2,3) //[1, 2, 3]
var d = Array.of(1,2,3) //[1, 2, 3]
//创建单值数组
var e = [3] // [3]
var f = [3] // [3]
var g = new Array(3) // [empty × 3]
var h = Array(3) // [empty × 3]

//删除元素===================
var arr= [1,2,3,4,5,6]
// 1.改变数组长度删除
arr.length = 5 // [1, 2, 3, 4, 5]
arr.length = 0 // 清空数组 []
// arr.splice(index,要删除的个数,...args)  args为要添加的元素;返回的是删除的元素
arr.splice(2,3,9,8,7) //返回 [3, 4, 5],arr值变为:1, 2, 9, 8, 7, 6]

//数组反转--------------  reverse()
[4,2,8].reverse() //[8, 2, 4]
// 字符串反转:split()->字符转为数组   join()->数组转支付
'hello'.split('').reverse().join('') // olleh

//数组排序 sort()
[1,5,6,3,2].sort() //  [1, 2, 3, 5, 6]
[1,5,6,3,2].sort((a,b)=>b-a) //  [6, 5, 3, 2, 1]

//数组连接concat()
[1,2].concat(3) // [1, 2, 3]
[1,2].concat(3,6,3)  [1, 2, 3, 6, 3]

//数组裁切-> slice(startIndex,endIndex)不改变原数组
var arr=[1,2,3,4,5,6] 
arr.slice(1) //[2, 3, 4, 5, 6]
arr.slice(1,3) //[2, 3]
arr.slice(1,-2) //  [2, 3, 4]

for in 和for of的区别

arguments函数传的参数

函数柯里化

把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

// 普通的add函数
function add(x, y) {
    return x + y
}

// Currying后
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

好处

1. 参数复用
2. 提前确认
3. 延迟运行
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = Array.prototype.slice.call(arguments);

    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        _args.push(...arguments);
        return _adder;
    };

    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}

add(1)(2)(3)                // 6
add(1, 2, 3)(4)             // 10
add(1)(2)(3)(4)(5)          // 15
add(2, 6)(1)                // 9

回调和闭包

  • 回调函数,官方解释:当程序跑起来时,应用程序会时常通过API调用库里预先备好的函数。但是有些库函数却要求应用先传给他一个函数,好在合适的时候调用,以完成目标任务。这个被传入、后又被调用的函数被称为回调函数。

    简单的说,回调就是回溯,先定义好将要使用的函数体,然后使用时再调用这个函数,通常把callback作为一个参数传入先定义的那个函数。

    function doSomething(callback){
     callback(1,2);
    }
    function numberAdd(a,b){
     document.write(a+b);
    }
    doSomething(numberAdd);//3
    
    function Thing(name){
     this.name = name;
    }
    //在Thing类里加入doSomething方法,这里使用了构造器调用模式
    Thing.prototype.doSomething = function(callback){
     callback(this.name);
    };
    function showName(name){
     document.write(name);
    }
    var t = new Thing("zhangsan");
    t.doSomething(showName);//zhangsan
    
  • 闭包是指有权访问另一个函数作用域中的变量的函数,从外部读取局部变量,有下述特性:

    1. 函数嵌套函数;
    2. 函数内部可以引用外部的参数和变量;
    3. 参数和变量不会被垃圾回收机制回收。 好处:
    4. 希望一个变量长期驻扎在内存中
    5. 避免全局变量的污染
    6. 私有成员的存在 使用场景:
    7. 可以读取函数内部的变量
    8. 让这些变量的值始终保持在内存中。

javascript的垃圾回收原理:

  1. 在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
  2. 如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
function outer(){
 var val = 0;
 return function (){
  val += 1;
  document.write(val + "<br />");
 };
}
var outObj = outer();
outObj();//1,执行val += 1后,val还在
outObj();//2
outObj = null;//val 被回收
var outObj1 = outer();
outObj1();//1
outObj1();//2

字符串

substr,splice的区别

模板字符串

var c = '1234'
var d ='sssss'
function a(strings, ...args){ console.log(strings,args)}
console.log(a`this is my ${c} dhihgeig ${d}`)
//(3) ["this is my ", " dhihgeig ", "", raw: Array(3)] (2) ["1234", "sssss"]


正则表达式

内置对象

Math

Math.PI //圆周率3.141592653589793
Math.abs(-6) //绝对值 6
Math.sin(Math.PI/2) // 参数的正弦 1
Math.floor(3.98) //向下取整 3
Math.ceil(3.1) //向上取整 4
Math.pow(10,3) //指数运算 1000
Math.sqrt(9) //  平方根3
Math.log(10)// 以e为底的自然对数值2.302585092994046
Math.exp(1) //常数e的参数次方2.718281828459045
Math.trunc(2.345) //将数字的小数部分去掉,只保留整数部分2

Math.random() //返回一个0到1之间的随机数
function getRandom (min, max) {
	return	Math.round(Math.random()*(max - min))
}
console.log(getRandom(0, 100)); // 输出0到100的随机整数
var ary = ['red', 'orange', 'yellow', 'blue', 'green']
function getRandom (min, max) {
		 return	ary[Math.round(Math.random()*(max - min))]
	}
console.log(getRandom(0, ary.length-1)); // 输出数组里随机的一个当前项


Math.max(5, 1, 9, 3, 7) //最大值 9
console.log(Math.min(5, 1, 9, 3, 7)) // 最小值 1
//获取数组的最大值合最小值,采用apply改变this指向的方式直接获取最大值和最小值
var arr = [5, 1, 9, 3, 7];
console.log(Math.max.apply(null, arr))   // 输出 9
console.log(Math.min.apply(null, arr))  // 输出 1

//Math.round() 四舍五入
console.log(Math.round(3.87)) // 输出 4 console.log(Math.round(3.39)) // 输出 3

Date

Date() //"Mon Aug 02 2021 21:06:38 GMT+0800 (中国标准时间)"
new Date() // Mon Aug 02 2021 21:06:48 GMT+0800 (中国标准时间)
new Date('12/11 15:21') // Tue Dec 11 2001 15:21:00 GMT+0800 (中国标准时间)


返回的都是Date对象相应的值, 例子是: **202182日 星期一 210145秒**
var now = new Date(); 
now; // => Mon Aug 02 2021 21:01:45 GMT+0800 (中国标准时间)
now.getDate();	// => 2, 返回Date对象的日期值, 2号
now.getDay();	// => 1, 返回星期值, 表示星期几, 这里是星期一, 注意0表示星期日, 1 ~6分别表示星期一至星期六
now.getFullYear();	// => 2018, 返回年份值, 完整4位数的格式, 建议使用这个API
now.getHours();	// => 21, 返回小时值
now.getMilliseconds();	// => 713, 返回毫秒值
now.getMinutes();	// => 1, 返回分钟值
now.getMonth();	// => 7, 返回月份值, 这里是8月!! 月份也是个特殊值, 介于0 ~11表示1月 ~12月
now.getSeconds();	// => 45, 返回秒数值,
now.getTime();	// => 1627909305713, 返回毫秒值(时间戳), 注: 这个**没有getUTCTime()方法**, 因为这个值和时区无关
now.getTimezoneOffset();	// => -480, 返回当前日期的本地表示与UTC表示之间相差的**分钟数**, 注意返回值依赖于指定日期的夏令时是否有效

//设置/更改时间, get和set是相对应的,3.  日期和时间对象的转换:
var now = new Date(); 
now;	// => Sat Dec 08 2018 18:21:14 GMT+0800 (中国标准时间)
now.setDate(15); 
now;	// => Sat Dec 15 2018 18:21:14 GMT+0800 (中国标准时间)
转换的时间例子是**2018128日 星期六 182114秒**
now.toDateString();	// => "Sat Dec 15 2018", 返回一个表示日期部分的字符串, 使用本地时区
now.toGMTString();	// => "Sat, 15 Dec 2018 10:21:14 GMT", 将Date转换为字符串, 已弃用, 建议使用toUTCString().
now.toISOString();	// => "2018-12-15T10:21:14.743Z", 将Date转字符串, 以ISO-8601标准和以时区为"Z"的UTC时间表示形式
now.toJSON();	// => "2018-12-15T10:21:14.743Z", 将Date对象JSON序列化, 返回值和toISOString()一样
now.toLocaleDateString();	// => "2018/12/15", 返回一个表示日期部分的字符串, 使用本地时区, 本地时间格式
now.toLocaleString();	// => "2018/12/15 下午6:21:14", 将Date转换为字符串
now.toLocaleTimeString();	// => "下午6:21:14", 返回一个表示时间部分的字符串
now.toString();	// => "Sat Dec 15 2018 18:21:14 GMT+0800 (中国标准时间)", 本地时区将Date转换为字符串
now.toTimeString();	// => "18:21:14 GMT+0800 (中国标准时间)", 返回一个表示时间部分的字符串
now.toUTCString();	// => "Sat, 15 Dec 2018 10:21:14 GMT", 用世界时间将Date转换为字符串 
now.valueOf();	// => 1544869274743, 将Date转为对应的内部毫秒格式

JSON.stringfy(object,?,缩进值)

set

  • 值不重复
  • set.has()
  • set.forEach
  • set.delete
  • set.clear()

map

var map = new Map()
map.set(1,'值1')
map.set({key:2},'值2')
map.set('key 3','值3')
console.log('map') //Map(3) {1 => "值1", {…} => "值2", "key 3" => "值3"}
console.log(map.get(1)) //值1
console.log(map.get({key:2})) // undefined
var objkey = {key:2}
map.set(objkey,'new 值')
console.log(map.get(objkey)) // new 值
console.log(map.get('key 3')) // "值3"

map.has('key 3') // 判断key是否存在 true

map.forEach((value,key)=>{console.log(value,key)}) //n

var iterator = map.entries()
console.log(iterator) // MapIterator {1 => "值1", {…} => "值2", "key 3" => "值3", {…} => "new 值"}
iterator.next() // {value: Array(2), done: false}done: falsevalue: Array(2)0: 11: "值1"length: 2[[Prototype]]: Array(0)[[Prototype]]: Object
iterator.next()// {value: Array(2), done: false}  value: (2) ["key 3", "值3"]
terator.next().value // ["key 3", "值3"]

for (let [key,value] of map){console.log(key,value)}
map.delete(1) // 删除Map(3) {{…} => "值2", "key 3" => "值3", {…} => "new 值"}

异常

正常js遇到异常不会向下执行,在try catch里捕获的异常不会影响后续代码执行
try{
    //控的代码,如:
    var emp = undefined
    console.log(emp.nme)
}catch(err){
   //异常的处理
    console.error('错误:' ,err)
}finally{
    console.log('总会执行')
}
console.log('这行会执行')

易混知识点

闭包vs回调

setTimeout模拟setInterval