JS常用方法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

一、取整方法

1.ParseInt()函数可解析一个字符串,并返回一个整数。

ParseInt(string, radix)   //第二个参数表明进制
参数描述
string必须。当第一个string参数以‘0x’开头则按16进制解析。
radix可选。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN,特殊情况为0,有可能转换正确。如果缺少第二个参数,默认十进制。

返回结果一律十进制

parseInt("10");			//返回 10
parseInt("19",10);		//返回 19 (10+9)
parseInt("11",2);		//返回 3 (2+1)
parseInt("17",8);		//返回 15 (8+7)
parseInt("1f",16);		//返回 31 (16+15)
parseInt("010");		//未定:返回 10 或 8

特殊情况,数字 英文 空格 掺杂的string
1。只能解析以数字或者空格开头的string,截止到出现英文或空格时停止(也就是说中间的空格和英文等同对待)
2.单独空格也不能解析
3.能识别正负号 + -

//以数字开头
parseInt('123abc123')   //123
//以英文开头
parseInt('a1a')        //NaN
//以空格开头
parseInt(' 123a2')    //123
//以数字或空格开头且中间有空格
parseInt('123 456')   //123
parseInt(' 123 2a2') //123
//单独空格
parseInt(' ')       //NaN
//带正负号
parseInt(' -100')   //-100
parseInt(' +100')   //100

2.其他取整方法

Math.floor(5.55)     //向下取整 结果为5 
Math.floor(5.99)    //向下取整 结果为5 
Math.ceil(5.21)     //向上取整,结果为6 
Math.ceil(5.88)     //向上取整,结果为6 
Math.round(5.78)   //四舍五入 结果为6 
Math.round(5.33)   //结果为5 

二、Math.random()

Math.random():结果为0-1间的一个随机数(包括0,不包括1) 。

//获取start到end区间的随机整数 
 function random(start,end){
    return  ParseInt(Math.random()*(end-start+1)+start)
    }

三、Number

Number(parameter):将parameter转化为一个数字型

参数描述
parameter必须。不同于ParseInt参数只能为字符串,Number参数可以是字符串,数组,对象,null,undfind等
Number(1.1) //log 1.1
Number(“1.1”) //log 1.1
识别小数点
Number(1.00) //log 1
Number(“1.00”)//log 1
//可以 Number(“1.00”).toFixed(2)保留两位小数时防止出现上一种情况。
toFixed(2)返回的是字符串。
注意:
  1. parameter 为字符串比ParseInt规则更严格,字符串必须全是数字,开头和结尾空格是被允许的
  2. parameter 为null, 布尔值false, 空字符串,空格字符串,空数组[ ], 转化为0;
  3. parameter 为长度为1的数组会被当作字符串,规则见1
  4. parameter 为带英文的字符串, 对象,函数,内容长度大于1的数组,undfind 会被转化NaN(意思为不是一个数)
  5. parameter 为布尔值,true转化为1,false转化为0
console.log(Number(" 100 "));    //100
console.log(Number(' 123abc'));  //NaN

var a = "+100";
alert(Number(a)); // 100 

var a1="000100";
alert(Number(a1));//100

var a2 = "";
alert( Number(a1) ); // 0

var a3 = "  ";
alert( Number(a1) ); // 0

var a4 = []; //[""]  [123]  ["123"] [1,2,3]
alert( Number(a4) ); // 0  0  123  123  NaN

var a5 = null;
alert( Number(a5) ); // 0

//undfind
var a6;
alert( Number(a6) ); // NaN

var a7=function(){alert(0)};
alert( Number(a7) ); // NaN

var json={abc:123}
alert( Number(json) ); // NaN

 Number(true) // 1
 Number(false) // 0

四、isNaN

标题isNaN存在的意义

由于NaN是唯一一个不等于自身的值,所以它不像其他值,可以用相等操作符来判断是否等于自身。比如undefined == undefined和undefined === undefined都会返回true,而NaN == NaN和NaN === NaN都会返回false,所以isNaN()就诞生了.

原理

isNaN函数接受一个参数,原理是先尝试将参数转换为数值型,调用的是Number()方法,再进行判断。

返回值(会Number转化规则)

返回 true: NaN、对象(除包含单个数值的数组)、undefined、不能用Number()方法转为number类型的字符串
返回false: 数值、null、布尔值、能用Number()方法转为number类型的字符串、包含单个数值的数组

isNaN([])              //false 

isNaN(["12"])		  //false 

isNaN(null)		      //false 

isNaN({})		      //true

isNaN(["1", "2"])	  //true

isNaN([true])		  //true

isNaN(true),		  //false

isNaN(false))		  //false 

————————————————
版权声明:本文为CSDN博主「小白张幺幺」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zzh1251994430/article/details/108023729

五、typeof

typeof操作符返回一个字符串,表示未经计算的操作数的类型。

类型结果
Undefined“undefined”
Null , [ ] , 任何其他对象“object”
Boolean“boolean”
Number,NaN“number”
String“string”
Symbol (ECMAScript 6 新增)“symbol”
宿主对象(由JS环境提供)Implementation-dependent
函数对象“function”
//全为true

// Numbers
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管NaN是"Not-A-Number"的缩写
typeof Number(1) === 'number'; // 但不要使用这种形式!
 
// Strings
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof总是返回一个字符串
typeof String("abc") === 'string'; // 但不要使用这种形式!
 
// Booleans
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(true) === 'boolean'; // 但不要使用这种形式!
 
// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';
 
// Undefined
typeof undefined === 'undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined'; 
 
// Objects
typeof {a:1} === 'object';
 
// 使用Array.isArray 或者 Object.prototype.toString.call
// 区分数组,普通对象
typeof [1, 2, 4] === 'object';
 
typeof new Date() === 'object';
 
// 下面的容易令人迷惑,不要使用!
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String("abc") === 'object';
 
// 函数
typeof function(){} === 'function';
typeof class C{} === 'function'
typeof Math.sin === 'function';
typeof new Function() === 'function';

六、isNumber

我们可以根据typeof 和isNaN封装isNumber函数

function isNumber(obj) {
    return typeof obj === 'number' && !isNaN(obj)
}

七、indexOf

indexOf(parameter):可以判断一个元素是否在数组中存在,或者判断一个字符是否在字符串中存在,如果存在返回该元素或字符第一次出现的位置的索引,不存在返回-1。

注意三点:
1.indexOf是数组方法也是字符串方法。
2.用于数组时,parameter参数可以是字符串,对象等
3.用于字符串时,parameter参数是字符串

//用于数组,parameter参数是字符串时
var arr = [1, 2, 3];
console.log(arr.indexOf(2));    //打印结果为1

//用于数组,parameter参数是引用型对象时会出现问题
var arr = [{name:"racyily",age:22},{name:"susan",age:18}];
var obj = {name:"susan",age:18};
console.log(arr.indexOf(obj));  //打印结果为-1
//改进
var arr = [{name:"racyily",age:22},{name:"susan",age:18}];
var arr2 = arr[1];
console.log(arr.indexOf(arr2));  //打印结果为1
//结论:数组中存放的是对象或者数组的话,必须是该对象的引用,才可以使用indexOf得到正确的索引值

八、split

split()方法是对字符串的操作;splice()和slice()是对数组的操作。slice()也可用于字符串。

split(separator,howmany)是字符串方法,把一个字符串分割成内容为字符串的数组。

参数描述
separator 必需字符串或正则表达式,从该参数指定的地方分割 string
howmany可选该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
//无howmany
"2:3:4:5".split(":")	//将返回["2", "3", "4", "5"]
"|a|b|c".split("|")	    //将返回["", "a", "b", "c"]

//有howmany
"hello".split("", 3)	//可返回 ["h", "e", "l"]

九、splice

splice方法可以用来对js的数组进行删除,添加,替换等操作。

  1. 删除功能,第一个参数为第一项位置,第二个参数为要删除几个。

用法:array.splice(index,num),返回值为删除内容,array为结果值。
在这里插入图片描述
2. 插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项)。

用法:array.splice(index,0,insertValue),返回值为空数组,array值为最终结果值。
在这里插入图片描述
3. 替换功能,第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项)。

用法:array.splice(index,num,insertValue),返回值为删除内容,array为结果值。
在这里插入图片描述

十、substring,substr,slice

都是字符串方法
substring(start,end):方法用于提取字符串中介于两个指定下标之间的字符

参数描述
start必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。
end可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾。

返回值:
一个新的字符串,该字符串值包含 stringObject 的一个子字符串,其内容是从 start 处到 stop-1 处的所有字符,其长度为 stop 减 start。

说明:
1.substring 方法返回的子串包括 start 处的字符,但不包括 end 处的字符。
2.如果 start 与 end 相等,那么该方法返回的就是一个空串(即长度为 0 的字符串)。
3.如果 start 比 end 大,那么该方法在提取子串之前会先交换这两个参数。
4.如果 start 或 end 为负数,那么它将被替换为 0。

//各种情况覆盖
var str = "0123456789"; //长度10
alert(str.substring(2,5));----------"234"
alert(str.substring(2,12));---------"23456789"
alert(str.substring(2,2));----------""
alert(str.substring(2,0));----------"01"
alert(str.substring(-1,5));---------"01234"
alert(str.substring(2,-2));---------"01"
alert(str.substring(-1,-5));--------""

substr(start , length ):方法用于返回一个从指定位置开始的指定长度的子字符串。

参数描述
start所需的子字符串的起始位置。字符串中的第一个字符的索引为 0。
length在返回的子字符串中应包括的字符个数。

说明:
1.如果start为负数,a:并且有长度,则start=str.length+start。结果也为负数则start=0,
b:没有长度,从后数开始截取,没有-0,所以-1是第一位。
2.如果 length 为 0 或负数,将返回一个空字符串。
3.如果没有指定该参数,则子字符串将延续到stringObject的最后。

//各种情况覆盖
var str = "0123456789"; //长度10
alert(str.substr(0));---------------"0123456789"
alert(str.substr(5));---------------"56789"
alert(str.substr(10));--------------""
alert(str.substr(12));--------------""
alert(str.substr(-5));--------------"56789"
alert(str.substr(-10));-------------"0123456789"
alert(str.substr(-12));-------------"0123456789"
alert(str.substr(0,5));-------------"01234"
alert(str.substr(0,10));------------"0123456789"
alert(str.substr(0,12));------------"0123456789"
alert(str.substr(2,0));-------------""
alert(str.substr(2,2));-------------"23"
alert(str.substr(2,5));-------------"23456"
alert(str.substr(2,12));------------"23456789"
alert(str.substr(2,-2));------------""
alert(str.substr(-1,5));------------"9"
alert(str.substr(-1,-5));-----------""  

slice可以用于字符串也可以用于数组,string.slice(start,end)
arrayObject.slice(start,end)
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2指倒数第二个元素,以此类推。

end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回一个新的数组,包含从 start(包含) 到 end (不包括该元素)的 arrayObject 中的元素。

十一、toString(可以获取不同进制数字)

toString()函数用于将当前对象以字符串的形式返回。

参数说明

都知道javascript的基本类型有五种,分别是Number、String、Undefined、null和Boolean;
内置对象有Array、Boolean、Object、Function(不要以为这不是内置对象)、Number、String等,接下来,可以使用该方法。

Array
var a1 = ["tom",23];
a1.toString();
输出:"tom,23"
var a2 = [];
a2.toString();
Boolean

如果布尔值是true,则返回”true”。否则返回”false”。

var b1 = new Boolean(false);
b1.toString();
输出"false"
Object
var o1 = {name: 'jackwen',age: 23}
o1.toString();
输出:"[object Object]"
Function

返回如下格式的字符串,其中 functionname 是一个函数的名称,此函数的 toString 方法被调用: “function functionname() { [native code] }”

function func() {
   console.log("I am a function");
}
func.toString();
输出:"function func() {
   console.log("I am a function");
}"
Number
var n1 = Number(10);
n1.toString();//默认10进制
n1.toString(2);//2进制
n1.toString(8);//8进制
输出:
"10"
"1010"
"12"
Number

返回 String 对象的值。

var s = "I am a string";
s.toString();
输出:"I am a string"

————————————————
版权声明:本文为CSDN博主「德莱问前端」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jackwen110200/article/details/54574181

十二、map

map() 方法只能被数组调用,调用后会创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

var array1 = [1,4,9,16];
const map1 = array1.map( function (x) {
      return x * 2
    });
console.log(map1);  //> Array [2,8,18,32]

函数应该使arr中的每个值被操作后都要返回一个新值作为新arr中的值

//出现问题代码
var array1 = [1, 4, 9, 16];
 
const map1 = array1.map(x => {
    if (x == 4) {
        return x * 2;
    }
});
 
console.log(map1); // > Array [undefined, 8, undefined, undefined]

结果:与预期的[1,8,9,16]截然不同,
原因:只是增加了一个条件,即x的值为4时才乘以2,之所以会出现undefined,是因为map()方法创建了一个新数组,但新数组并不是在遍历完array1后才被赋值的,而是每遍历一次就得到一个值。所以,下面这样修改后就正确了

var array1 = [1, 4, 9, 16];
 
const map1 = array1.map( function (x) {
      if (x == 4) {
        return x * 2;
      }
      return x;
    });

十三、filter

filter ()是数组方法,用于把Array的某些元素过滤掉,然后返回剩下的元素。

原理:和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

例如,在一个Array中,删掉偶数,只保留奇数,可以这么写

var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
    console.log(element); // 依次打印'A', 'B', 'C'
    console.log(index); // 依次打印0, 1, 2
    console.log(self); // self就是变量arr
    return true;
});

十四、every

array.every(function(currentValue,index,arr), thisValue)
every()是数组方法,针对数组中的每一个元素进行比对,只要有一个元素比对结果为false则返回false,反之要所有的元素比对结果为true才为true

var a = [1,2,3,4,5,6];
var b = a.every(function(x){
    return x < 8;
});
var c = a.every(function(x){
    return x < 5;
})
console.log(b); //这里返回true
console.log(c); //这里返回false

十五、some

some()是数组方法,针对数组中的每一个元素,但是这个方法是,只要有一个元素比对结果为true,返回结果就为true,反之要所有的元素比对结果为false才为false

var a = [1,2,3,4,5,6]
var b = a.some(function(x){
        return x > 10;
    })
var c = a.some(function(x){
        return x > 5;
    })
console.log(b) //这里返回false
console.log(c) //这里返回true

十六、forEach

forEach() 用于数组的遍历,不能遍历对象
但有时候不能遍历node(元素)数组,显示not a function ,有时可以使用,还不清楚

//foreach遍历添加数组,每次循环如果数组变化则根据新的数组和累加的索引遍历,索引index不超过原数组长度。
//index无法操作 如index-- 不生效。
    let arr = [1, 2]
    arr.forEach((item, index) => {
      arr.push(3)
      console.log(item, index);  // 1 0 , 2  1
    })
    
    console.log(arr); [1, 2,3,3]
    let arr = [1, 2, 3, 4, 5]
    arr.forEach((item, index) => {
      arr.splice(0, 1)
      console.log(item, index);   // 1 0 ,3 1 , 5 2
      // console.log(arr[index]); 
    })
    console.log(arr);
//语法
Array.forEach(function(value , index , array){ 
  //value为遍历的当前元素,index为当前索引,array为正在操作的数组
  //do something
},thisArg)      //thisArg为执行回调时的this值

var arr = [1,2,3,4];
var sum =0;
arr.forEach(function(value,index,array){

 array[index] == value; //结果为true

 sum+=value; 

 });

console.log(sum); //结果为 10

十七、for in和for of

for in: 遍历对象中的各个属性,也可以遍历数组,参数时索引值
for of:遍历数组,不能遍历对象,参数是值

//for in 遍历对象
//key为属性名,user[key]为属性值
let user = {
  name: "SJ",
  "my age": 18
}
for(const key in user) {
  console.log(key + ":" + user[key])
}
// 运行结果
// name:SJ
// my age:18

// 扩展
// 打印属性,
console.log(Object.keys(user));  
// 打印属性值
console.log(Object.values(user));
// 属性名和属性值一起获取
console.log(Object.entries(user));

//for in 遍历数组
let arr = [12, 23, 45, 56];
    for (const key in arr) {
      console.log(arr[key]);
    }

//for of不能对 对象遍历
const person = {
  name: 'Lydia',
  age: 21,
};

for (const item of person) {
    console.log(item);
  }
//TypeError: person is not iterable


//for of 对数组遍历
let arr = [12, 23, 45, 56];
    for (const value of arr) {
      console.log(value );
    }




在这里插入图片描述

如果对象的键是数字

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>JS中对象key为数字的使用</title>
	</head>
	<body>
		<div>
			
		</div>
		<script >
			var obj = {
				
			};
			var key0 = 0;
			obj[key0] = 0;
			console.log(obj)//结果是 {0:0}
			var key1 = 1;
			obj.key1 = 1;
			console.log(obj);// 结果是{0:0,key1:1}
			// key值为数字,不能使用.进行赋值,使用[]
			obj[4] = 4;
			obj[3] = 3;
			obj[6] = 6;
			obj[5] = 5;
			console.log(obj);//结果是{0:0,3:3,4:4,5:5,6:6}
			// 看到了吗,使用数字作为key的好处是,自动为我们进行了排序;这样比数组方便很多,譬如筛选条件,我们就可以使用对象保存,
			// 这样可以保证无论先选择哪一行的筛选条件我们都是按照既定的顺序展示;使用数组的话我们还要自己手动去排序
		</script>
	</body>
</html>

不是数字也可以像数组一样访问

let ss = {
      'a': 'b',
      'c': 'd'
    }
    console.log(ss['a'], ss.a); // b b

十七、typeof和instanceof

typeof判断数据类型,但数组和对象结果都是对象
instanceof更强大,能区分数组和对象
注意

  1. ‘h1’ instanceof String //false
    因为 'h1’是一个字符串值,只有new String(‘h1’) instanceof String 为true
    讲解
  2. typeof [] 结果是’object’, 一般用[] instanceof Array 或者 Array.isArray([ ]) //建议用 Array.isArray()
    console.log(typeof []);            //'object'
    console.log(typeof {});            //'object'
    console.log([] instanceof Object); // true
    console.log([] instanceof Array);  // true
    console.log({}instanceof Object);  // true
    console.log({}instanceof Array);   // false

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

// 定义构造函数
function C(){}
function D(){}

var o = new C();


o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype


o instanceof D; // false,因为 D.prototype 不在 o 的原型链上

o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上

十八、函数对象和普通对象

对象分为:函数对象和普通对象

    let f1 = function fs() {}
    let f2 = new Function()
    let f3 = new Object()
    let f4 = new fn()
    let f5 = new f1()
    
    //function function function object object object
    console.log(typeof fn, typeof f1, typeof f2, typeof f3, typeof f4, typeof f5);
    
    //function function function true true
    console.log(typeof Object, typeof Array, typeof Function, Object instanceof Function, Array instanceof Function,Function);

十九、call和apply修改函数this指向

/**
 * 以下三种形式都可以调用fun函数
 * 区别:
 * 在调用call()和apply()时,可以将一个对象指定为第一个参数
 * 在javascript严格模式中,在调用函数时,第一个值均成为this值,
 * 在JavaScript非严格模式中,如果第一个参数值是null或undefined,他会使用全局变量代替
 * 因此,这两个方法可以用来修改this值
 */
function fun() {
    console.log(this.name);
}
var obj1 = {name:"顺悟空"};
var obj2 = {name:"猪八戒"};

fun();// <empty string> this为window
fun.call(obj1);//猪八戒
fun.apply(obj2);//孙悟空

/**
 * call()方法可以将实参在对象之后传递
 * 而apply()方法需要将实参统一封装在数组中传递
 *
 */
function con(a,b) {
    console.log("a="+a);
    console.log("b="+b);

}
con();// a=undefined b=undefined
con.call(obj1,3,5);//a=3,b=5
con.apply(obj1,[1,3]);//a=1,b=3

// "use strict";//使用严格模式

/**
 * 以下三种形式都可以调用fun函数
 * 区别:
 * 在调用call()和apply()时,可以将一个对象指定为第一个参数
 * 在javascript严格模式中,在调用函数时,第一个值均成为this值,
 * 在JavaScript非严格模式中,如果第一个参数值是null或undefined,他会使用全局变量代替
 * 因此,这两个方法可以用来修改this值
 */
function fun() {
    console.log(this.name);
}

var obj1 = {
    name: "顺悟空",
    sayname: function () {
        alert(this.name)
    }
};

var obj2 = {name: "猪八戒"};

obj1.sayname();//顺悟空
obj1.sayname.apply(obj2);//猪八戒


二十、bind修改函数this指向

看收藏的csdn
三者区别:call和apply调用时修改(结构函数除外),bind在调用前修改

二十一、in和hasOwnProperty区别

in判断的是对象的所有属性,包括对象实例及其原型的属性;
而hasOwnProperty则是判断对象实例的是否具有某个属性(不包括原型链上的属性)。

function person(name) {
      this.name = name

    }
    var jam = new person("jam")
    person.prototype.eat = function () {
      console.log("chi");
    }
    person.prototype.c = 3
    
    //实例对象自身存在的属性(方法)
    "name" in jam                //true
    jam.hasOwnProperty("name"),	//true	
    
    //实例对象的原型对象存在的属性(方法)
    "eat" in jam, 				//true
    jam.hasOwnProperty("eat")	//false
    

二十二、reverse()和join()

  1. JavaScript中的Array对象提供了一个reverse()方法用于反转(颠倒)数组中的元素。要注意的是,这个方法会改变原来的数组,而不会创建新的数组。
  2. join方法可以把Array对象用不同的分隔符来构建这个字符串。join方法值接受一个参数,即用作分隔符的字符串(默认是“,”),然后返回所有数组项的字符串。
var arr = ['yanggb1', 'yanggb2', 'yanggb3'];

console.log(arr.reverse()); // ['yanggb3', 'yanggb2', 'yanggb1']
console.log(arr); // ['yanggb3', 'yanggb2', 'yanggb1']


var arr = ["red","yellow","blue"];
var array = [];
//join方法的参数不传或者传入undefined会默认用逗号分隔。
array = arr.join(undefined);
console.log(array);     // red,yellow,blue。
array = arr.join(" | ");
console.log(array);    //red | yellow | blue

可以利用split() ,reverse(),join()实现字符串的反转效果

var str = '2020-04-01';

console.log(str.split('-').reverse().join('-')); // 01-04-2020

二十三、replice()

字符串方法中的replace方法,该方法主要用于将字符串中符合匹配条件的字串替换成其他的字符串,返回替换后的字符串,且原字符串不变。

	var newStr = str.replace(regexp|substr, newSubStr|function)
//参数1:匹配条件:可以是正则表达式(regexp)或者字符串(substr)

//如果参数1是字符串的话仅匹配一次
   var  str = '#home#home'
   var pattern1= 'home'
   var newStr1 = str.replace(pattern1, 'home1') //得到newStr1的结果为"#home1#home"
   
//如果参数1是正则表达式的话
//先考虑没有全局标志g和捕获组的情况:即在没有全局标志g和捕获组的情况下,也是只匹配一次。
   var  str = '#home#home'
   var pattern2= /home/
   var newStr2 = str.replace(pattern2, 'home1') //得到newStr2的结果为"#home1#home"

//如果在有全局标志g的情况下:即在有全局标志g的情况下可以实现全局多次匹配。
	var  str = '#home#home'
	var pattern3= /home/g
	var newStr3= str.replace(pattern3, 'home1') //得到newStr3的结果为"#home1#home1"
   

二十四、trim

字符串方法trim用于去掉字符串开头和结尾的空格,返回去掉空格以后的字符串。

二十五、toFixed()和round()

toFixed不是采用传统意义上的四舍五入法,而是银行家算法。所以在进行精度算法时,最好在后端计算,而且toFixed方法在不同的浏览器呈现的效果不同:

var a = 1.335;
console.log(a.toFixed(2));
//IE   1.34
//Chorme  1.33
 
var b = 1.345
//Chorme  1.34
 
var c = 1.355
//Chorme  1.35
 
var d = 1.365
//Chorme  1.36
 
var d = 1.375
//Chorme  1.37
 
var e = 1.385
//Chorme  1.38

银行家算法即:“四舍六入五成双”,当舍掉位是5时,要根据5前一位来判断是否舍入。当5前一位是奇数:舍5入1;当5前一位是偶数:舍5不进。(0为偶数)

(但同时发现:在chrome种,并不完全遵循所谓的银行家算法,所以在进行金额的换算时,应尽量避免使用toFixed()方法,同时它与后台java等语言的银行家舍入精度不同,可能造成接口验证失败)

round():

该方法是标准的四舍五入,使用方法:Math.round(Number);

如果想实现四舍五入的方法,建议重写toFixed()方法。

二十六、Math.abs()

Math.abs()是取绝对值。

二十六、navigator.geolocation对象

这个API得到了广泛的支持,并且使用得很多,所以还是很有必要学一下。使用地理定位API的时候会在浏览器弹出提示,让用户来决定是否允许访问地理信息

它在浏览器中的实现是navigator.geolocation,这个对象包括三个方法。

getCurrentPosition(): 获取当前的位置信息,接受三个参数

成功的回调函数: 接受一个position对象,包括coords、timestamp两个属性,
其中的coords属性包括以下属性:

latitude: 纬度
longitude: 经度
accuracy: 经纬度坐标的精度,以米为单位
altitude:以米为单位的海拔高度
altitudeAccuraxy: 海拔高度的精度,以米为单位
heading: 指南针方向,0表示正北
speed:速度,每秒移动多少米

失败的回调函数: 也会接受一个对象, 包含连个属性:

message: 错误的文本信息
code: 错误类型,1拒绝共享、2位置无效、3超时

可选的选项对象: 有三个 属性

enableHighAccuracy:表示尽可能的使用非常准确的值,但是不建议使用,除非的确需要获取非常准确的值,因为它需要更多的时间,而且在移动设备上很耗电
timeout: 毫秒为单位,表示等待位置信息的最长时间
maximumAge: 表示自从上一次获取位置开始的多长时间内不再获取坐标,直接使用上一次的

<p id="demo">点击按钮获取您当前坐标(可能需要比较长的时间获取):</p>
  <button onclick="getLocation()">点我</button>
  <script>
    var x = document.getElementById("demo");

    function getLocation() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
      } else {
        x.innerHTML = "该浏览器不支持获取地理位置。";
      }
    }

    function showPosition(position) {
      x.innerHTML = "纬度: " + position.coords.latitude +
        "<br>经度: " + position.coords.longitude;
    }

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

watchPosition(): 接受的参数和上面一样,表示跟踪用户的位置,与定时调用上面的方法效果相同。它会返回一个数值标识,用来取消监控操作,类似于定时器。

二十六、退出循环

跳出循环的方式:break,、return,、continue、抛出异常。
相同之处:都会将此时进行的语句停止。
不同之处:

break:是立即结束语句,并跳出语句,进行下个语句执行。
continue:是停止当前语句,继续执行该语句。
return:停止函数,必须放在函数里面,用于跳出函数和forEach循环,不能使用for循环
使用的语句环境不一样,break和continue是用在循环或switch语句中,return是用在函数语句中。

  1. for循环和for-in循环相同
//跳出本次循环continue:
  var arr = [0, 1, 2, 3, 4, 5];
   for (var i = 0, len = arr.length; i < len; i++) {
     if (i == 2) continue
     console.log(arr[i]);
   }
   //当i==2时,跳出本次循环,本次循环下面的代码不在执行。但是真个循环继续执行,直到循环条件为false
   //得到结果:0,1,3,4,5

//跳出整个循环break:
  for (var i = 0, len = arr.length; i < len; i++) {
     if (i == 2) break
     console.log(arr[i]);
   }
   //当i == 2时,使用break跳出整个循环,后面的循环条件不在执行,直接退出整个循环。
   //得到结果:0,1
   
//break也可以指定跳出外层循环或内层循环,不指定时默认跳出所在位置的循环
//指定跳出内层循环
 outer:
      for (var i = 0; i < 10; i++) {
        inter: for (var j = 0; j < 10; j++) {
          if (j > 5) {

            break inter;
          }
          console.log(i);
        }
      }
      
//指定跳出外层循环
  outer:
      for (var i = 0; i < 10; i++) {
        inter: for (var j = 0; j < 10; j++) {
          if (j > 5) {

            break inter;
          }
          console.log(i);
        }
      }
//多层循环嵌套
  var arr = [0, 1, 2, 3, 4, 5];
  var arr2 = ['a','b','c','d'];
  for (var i = 0, len = arr.length; i < len; i++) {
    if (i == 2) break
    console.log(arr[i]);
    for (var j = 0, len = arr2.length; j < len; j++) {
      console.log('内层',arr2[i]);
    }
  }
  //    //当i == 2时,使用break跳出整个循环,后面的循环条件不在执行,内层循环也不会执行直接退出整个循环。


  1. forEach循环
    退出一次循环,整个循环继续: return ;reutrn false ; return true ;
 var arr = [0, 1, 2, 3, 4, 5];
   arr.forEach((i)=>{
     if(i==2){
       return;
       // return false; //效果同上
       // return true; //效果同上
     }
     console.log(i);    //0,1,3,4,5  缺失2
   });
   // 在forEach循环中,return 返回任何值,都只能退出当前循环。

要想跳出整个forEach循环,可以使用抛异常的方式:

  var arr = [0, 1, 2, 3, 4, 5];
   arr.forEach((i)=>{
     if(i==2){
       throw 'jumpout';
     }
     console.log(i);
   });
   //得到结果:0,1

二十七、sort()数组排序

js中用方法sort()为数组排序。sort()方法有一个可选参数,是用来确定元素顺序的函数。
如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:

var arr = ["a", "b", "A", "B"];
arr.sort();
console.log(arr);//["A", "B", "a", "b"]

因为字母A、B的ASCII值分别为65、66,而a、b的值分别为97、98,所以上面输出的结果是 [“A”, “B”, “a”, “b”] 。
如果数组元素是数字呢,结果会是怎样?

var arr = [15, 8, 25, 3];
arr.sort();
console.log(arr);//[15, 25, 3, 8]

结果是 [15, 25, 3, 8] 。其实,sort方法会调用每个数组项的toString()方法,得到字符串,然后再对得到的字符串进行排序。虽然数值15比3大,但在进行字符串比较时”15”则排在”3”前面。显然,这种结果不是我们想要的,这时,sort()方法的参数就起到了作用,我们把这个参数叫做比较函数。

//比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,
//如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个正数。例子:
var arr = [23, 9, 4, 78, 3];
var compare = function (x, y) {//比较函数
    if (x < y) {
        return -1;
    } else if (x > y) {
        return 1;
    } else {
        return 0;
    }
}
console.log(arr.sort(compare));  // [3, 4, 9, 23, 78]       

结果为 [3, 4, 9, 23, 78] ,返回了我们想要的结果。如果要按降序排序,比较函数写成这样即可:

var compare = function (x, y) {
    if (x < y) {
        return 1;
    } else if (x > y) {
        return -1;
    } else {
        return 0;
    }
}

结果是 [“b”, 5] 。因为比较函数在比较时,会把先把字符串转化为数字,然后再比较,字符串b不能转化为数字,所以就不能比较大小。然而,当不用比较函数时,会比较ASCII值,所以结果是 [5, “b”] 。

如果数组项是对象,我们需要根据数组项的某个属性对数组进行排序,要怎么办呢?其实和前面的比较函数也差不多:

var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];
var compare = function (obj1, obj2) {
    var val1 = obj1.name;
    var val2 = obj2.name;
    if (val1 < val2) {
        return -1;
    } else if (val1 > val2) {
        return 1;
    } else {
        return 0;
    }            
} 
console.log(arr.sort(compare));

输出结果为 [Object { name=“wlz”, age=25}, Object { name=“zlw”, age=24}] ,可以看到数组已经按照 name 属性进行了排序。

二十八、reduce()

第一个参数: callback函数

执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数:

accumulator
累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。

currentValue
数组中正在处理的元素。

index 可选
数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。

array可选
调用reduce()的原数组

第二个参数: initialValue可选

作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

//求和
var total = [ 0, 1, 2, 3 ].reduce(
  ( acc, cur ) => acc + cur,
  0
);
 
// total  6

//累加对象里的值
let sum = [{x: 1}, {x:2}, {x:3}].reduce(
    (accumulator, currentValue) => accumulator + currentValue.x
    ,0
);
 
console.log(sum) // logs 6


//二维数组变一维
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
 ( acc, cur ) => acc.concat(cur),
 []
);
// [0, 1, 2, 3, 4, 5]



//计算数组中每个元素出现的次数
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
 
let countedNames = names.reduce(function (allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }


//按属性对object分类
var people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];
 
function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}
 
var groupedPeople = groupBy(people, 'age');
// groupedPeople is:
// { 
//   20: [
//     { name: 'Max', age: 20 }, 
//     { name: 'Jane', age: 20 }
//   ], 
//   21: [{ name: 'Alice', age: 21 }] 
// }

二十九、object.keys()

Object.keys()的用法
作用:遍历对象
返回结果:返回对象中每一项key的数组

	// 1. 定义一个对象
    var obj = { 0:'熊大',1:'熊二',2:'光头强' }
    // 2. 使用Object.keys()方法
    var keyValue = Object.keys(obj)
    // 3. 打印结果
    console.log(keyValue)  // 得到是:["0","1","2"]
    console.log(...obj.keys()); //错误

		let arr = [-1, 2, 3, 5]
  	  console.log(arr.keys()); //Array Iterator {}
     console.log(...arr.keys()); //1 2 3 4   不是数组

//总结:数组和object统一使用Object.keys(obj)或Object.keys(arr),二维数组用arr.keys()如map,一维数组set也要使用arr.keys()。

三十、set和map

set是不重复的数组,不能使用数组的方法包括length,有自己的方法和size

const s = new Set();

[2,3,5,4,5,2,2].forEach(x => s.add(x));
// Set结构不会添加重复的值

for(let i of s) {
  console.log(i);
}


// ## 初始化
// 例一 可以接受一个数组作为参数
const set = new Set([1,2,3,4,4,]);

// ...将一个数组转为用逗号分隔的参数序列
console.log([...set]);

// 例二
const items = new Set([1,2,3,4,5,5,5,5,]);
console.log(items.size);


// 例三 可以接受具有iterable接口的其他数据结构作为参数
const set2 = new Set(document.querySelectorAll('div'));
console.log(set.size);

// 类似于
const set2 = new Set();
document
    .querySelectorAll('div')
    .forEach(div => set.add(div));
console.log(set.size);

// set中NaN等于自身,其余比较相当于 ===
let set3 = new Set();
let a = NaN;
let b = NaN;
set3.add(a);
set3.add(b);
console.log(set3)

// 两个对象总是不相等的
let set4 = new Set();
set4.add({});  // 1
console.log(set4.size);

set4.add({});  // 2
console.log(set4.size);

const s = new Set();

s.add(1).add(2).add(2);

console.log(s.size);

console.log(s.has(1));
console.log(s.has(2));
console.log(s.has(3));

s.delete(2);
console.log(s.has(2));

// set转数组
const items = new Set([1,2,3,4,5]);
const array = Array.from(items);
console.log(array);

// 去除数组重复成员
function dedupe(array) {
  return console.log(Array.from(new Set(array)));
}

dedupe([1,1,2,3]);

let set = new Set(['red', 'green', 'blue']);

// 返回键名
for(let item of set.keys()) {
  console.log(item);
}

// 返回键值
for(let item of set.values()) {
  console.log(item);
}
// set 键名=键值

// 返回键值对
for(let item of set.entries()){
  console.log(item);
}

// 可以直接用 for of遍历Set
// for in 和 for of的区别是:in 是遍历对象,of是遍历值
for (let x of set) {
  console.log(x);
}

// set也有forEach()方法
set.forEach((value, key) => console.log(key + ' : ' + value));
// 此处forEach方法的参数是一个处理函数。

// 数组的 map 和 filter 方法也可以间接用于Set
let s = new Set([1,2,3]);

// map 将原数组映射成新数组
s = new Set([...s].map(x => x * 2));
console.log(s);

// filter返回过滤后的新数组
s = new Set([...s].filter(x => (x % 3) ==0));
console.log(s);

// 实现并集、交集、差集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);

let union = new Set([...a, ...b]);
console.log(union);

let intersect = new Set([...a].filter(x => b.has(x)));
console.log(intersect);

let difference = new Set([...a].filter(x => !b.has(x)));
console.log(difference);

// 在遍历操作中,同步改变原来的Set结构的两种变通方法

// 1.利用原Set结构映射出一个新的结构,然后赋值给原来的Set结构
let set1 = new Set([1,2,3]);
set1 = new Set([...set1].map(val => val *2));
console.log(set1);

// 2.利用Array.from
let set2 = new Set([1,2,3]);
set2 = new Set(Array.from(set2, val => val * 2));
console.log(set2);

map:初始化Map需要一个二维数组,或者直接初始化一个空Map。
特点:对象的键只能是字符串,map的键可以 是引用类型,由于键唯一,所以map也是不可重复的

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

map和set共同的方法

  //================= 遍历   keys()   values()   entries()    forEach() 
      //   由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。
        let res = s.keys()  //  键和值是一样的 
        console.log(res);
        let res1 = s.values()
        console.log(res, res1); 

        let res2 = s.entries()  // 键值对的组合
        console.log(res2);

        s.forEach((value, key) => {
            console.log(value,key);
        })

三十一、assign()

Object.assign() 方法将所有可枚举(Object.propertyIsEnumerable() 返回 true)和
自有(Object.hasOwnProperty() 返回 true)属性从一个或多个源对象复制到目标对象,返回修改后的对象。
sources是数组,里面是对象
Object.assign(target, …sources)

    let obj1 = {
            a:1, 
            b:2,
            teams:{
                name:'万仙山队'
            }
        }
        let obj2 = {
            a:1, 
            b:4,
            c:5
        }
 	 //  ============== 对象的拷贝   依然是浅拷贝
      Object.assign(obj1, obj2) 	 //较少使用
    //  使用{} 对象作为目标对象
      let res = Object.assign({}, obj1, obj2) //常使用
       res.teams.name = '凤凰山队'     //res 和 obj1 都会改变

三十二、Math.max() Math.min()

1、Math.max()函数只能传入一组参数来求最大值,所以如果是要用于求一个数组中的最大值时,可以用Math.max.apply(Math,array),把this值指向Math对象,则第二个参数可以传入任意数组。

2、当给Math.max()或Math.min()函数传参时,若参数中有非数值的项,则会返回NaN。

var max=Math.max.apply(Math,arr);//这里其实用var max=arr[0];也可以的
var min=Math.min.apply(Math,arr);//var max=arr[9]
Math.max(1,2) //2

三十三、for of和Iterator

    遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。 具备Iterator 接口的可以使用for of
    
    
    Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。


    Iterator 的遍历过程是这样的。
    (1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

    (2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

    (3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

    (4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

    每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束(false:未结束, true:结束)。

    原生具备 Iterator 接口的数据结构如下。

        Array
        Map
        Set
        String
        TypedArray
        函数的 arguments 对象
        NodeList 对象  

总结:具体对象没有iterator接口

  let person = {
            name:'小明',
            age:18,
            sex:'男',
            [Symbol.iterator]:function(){
                //  声明一个变量 存储 key键
                let  key = null;
                //  声明一个变量 记录指针的推进
                let index = 0;
                //  this 存储this指针
                let self = this;
                return {
                    next:function(){
                        if(key == null){
                             key =  Object.keys(self);
                        }                       
                        console.log(  index , key.length , self[key[index]], index >= key.length);
                        return {
                            value:self[key[index]],
                            done: ++index >= key.length 
                        }
                    }
                }
            }
        }

//person 对象部署了next函数就可以用for of
   for(let key of person){
            console.log(key);
        }

//也可以直接受用next方法
        let iterator = person[Symbol.iterator]();
        iterator.next()
        iterator.next()
        iterator.next()
        iterator.next()
        iterator.next()
        iterator.next()
        iterator.next()
        iterator.next()

三十三、arguments

arguments是函数实参的伪数组

function showargs() {
	console.log( arguments );
}

showargs(1,2,3,4,5);

在这里插入图片描述


    /**
     * 在调用函数时,浏览器每次都会传递两个隐含参数
     * 1.函数上下文的this
     * 2.封装实参的对象arguments
     *      -arguments是一个类(类似但不是)数组对象,也可以通过索引操作数据,也可以获取长度
     *      在调用函数时,我们所传递的实参都会封装在arguments中
     *       arguments.length可以用来获取实参长度
     *       即使不定义形参 也可以通过arguments来使用实参,只不过比较麻烦
     *        它还有一个属性叫callee
     *        这个属性对应一个函数对象,就是当前执行的函数对象
     */
    function fun() {
        console.log(arguments instanceof Array);//判断是否是数组 false
        console.log(Array.isArray(arguments));//判断是否是数组false
        console.log(arguments.length);//2,实参数的数量
        console.log(arguments[1]);//true
        console.log(arguments.callee==fun);//ture

    }
    fun("hellow",true);

三十三、多维数组转换为以为数组

[1,2,[3,4,[5,6]],7].flat(Infinity) //[1,2,3,4,5,6,7]    Infinity无穷,几维就写几,不确定就写Infinity。

三十四、find

参考连接
find()方法用于查找数组中符合条件的第一个元素,如果没有符合条件的元素,则返回undefined
callback:必须。为数组中每个元素执行的函数,该函数接受三个参数:
currentValue:必须。数组中正在处理的当前元素。
index:可选。当前元素的索引值。
arr:可选。当前元素所在的数组对象。
thisValue:可选。传递给函数的值一般用 “this” 值。
如果这个参数为空, “undefined” 会传递给 “this” 值

let arr1 = [1, 2, 3, 4, 5];
let num = arr1.find(item => item > 1);
console.log(num)  //輸出的結果是2


 var arr = [{
        id: 1,
        name: '张一',
        age: 25,
        class: '一班'
    }, {
        id: 1,
        name: '张二',
        age: 25,
        class: '二班'
    }, {
        id: 2,
        name: '张三',
        age: 25,
        class: '三班'
    }]
    let obj = arr.find(item => item.id == 1)
    console.log(obj); 
    // 结果:{id: 1, name: '张一', age: 25, class: '一班'}

三十四、递归

//如果数据是平级的,需要转换为树级(parid为0是一级,其他按parid决定父级)
//
let aArr=[
			{
				id:0,
				parent_id:0,
				a:1
			},
			{	
				id:1,
				parent_id:0,
				a:1
			},
			{
				id:2,
				parent_id:1,
				a:1
			},
			{
				id:3,
				parent_id:1,
				a:1
			},
			{
				id:4,
				parent_id:3,
				a:1
			},
			{
				id:5,
				parent_id:4,
				a:1
			},
		]

 // 一级菜单
        let parent = initRouter.filter(item => item.parent_id === 0)
        // 子级菜单
        let children = initRouter.filter(item => item.parent_id !== 0)
        // 递归函数
        const getTree = (parent, children) => {
            parent.map(p => {
                children.map((c, i) => {
                    // 判断是否为子节点
                    if (c.parent_id === p.id) {
                        // 拷贝整个子节点
                        let _c = JSON.parse(JSON.stringify(children))
                        // 把当前这一项子级删除
                        _c.splice(i, 1)
                        // 递归,再让子节点的这一项跟整个子节点做对比
                        getTree([c], _c)
                        // 判断父节点里面有没有children这个属性
                        if (p.children) {
                            p.children.push(c)
                        } else {
                            p.children = [c]
                        }
                    }
                })
            })
            return parent
        }
        const res = getTree(parent, children)
        console.log(res);

三十五、call、apply、bind三者的用法和区别

点击查看参考csdn
call、apply、bind都是改变this指向的方法
call、apply 会立即执行,前者需要一个个传值,后者需要放在一个数组里传值
bind不会立即执行,传值也是一个一个传

    let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);    // this:obj    a:1         b:2
    fn.call(1,2);        // this:1      a:2         b:undefined
    fn.call();           // this:window a:undefined b:undefined
    fn.call(null);       // this=window a=undefined b=undefined
    fn.call(undefined);  // this=window a=undefined b=undefined

fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);

document.onclick = fn.bind(obj);



 function f(y,z){
    return this.x+y+z;
  }
  //bind又有不是立即执行的,所以可以传值也可以不传,也可以传一部分,调用时再传一部分
  var m = f.bind({x:1},2);
  console.log(m(3)); // 6

三十六、数组快速转化为Number类型

      // 1.将字符串数组转化为数值型数组
      let strArr = ["1", "2", "3"];
      strArr.map(Number); // [1,2,3]  Number自动转换为number函数并把值传进去
 
      // 2.将数值型数组转化为字符串数组
      let numArr = [1, 2, 3];
      numArr.map(String); //  ["1", "2", "3"]
 
      // 3.将数值型数组转换为布尔值
      let numArr = [0, 1, 0, 1, 1];
      numArr.map(Boolean); // [false,true,false,true,true]
 
      // 4.混合类型也可以转换
      let newArr = [1, "2", "3", 4, 5];
 
      newArr.map(Boolean); // [true,true,true,true,true]
      newArr.map(String); //  ["1", "2", "3","4","5"]
      newArr.map(Number); //  [1,2,3,4,5]

注意
[12,1,3].map(parseInt) //[12, NaN, NaN]
//解析:parseInt会传入两个参数,第一个是需要转化的内容,第二个是进制,[12,1,3].map(parseInt)会自把index传入并当作第二个参数当做进制。
 

三十七、Date获取时间

介绍:YYYY-MM-DDTHH:mm:ss.000Z // 2023-04-24T15:30:00.000Z
ISO 8601 时间格式中的时间是 UTC (Coordinated Universal Time) 时间。
UTC 时间是一种全球统一的时间标准,它不受任何时区的影响。它是以格林威治时间(GMT)为基准的时间,与格林威治时间只有一小时的时差。(中国位于东八区,比ISO时间快8小时)

这个时间格式是 ISO 8601 标准时间格式。它包含以下部分:

YYYY: 4位数的年份
-MM: 2位数的月份
-DD: 2位数的日期
T: 时间和日期之间的分隔符
HH: 2位数的小时
:mm: 2位数的分钟
:ss: 2位数的秒
.000: 3位数的毫秒
Z: 时区指示符,表示为 UTC 时间,
例如:

2023-04-24T15:30:00.000Z 表示 2023 年 4 月 24 日 15 时 30 分 0 秒 (UTC 时间)
2022-12-31T23:59:59.999Z 表示 2022 年 12 月 31 日 23 时 59 分 59 秒 999 毫秒 (UTC 时间)
这种时间格式广泛用于计算机系统和 Web 应用程序中,因为它提供了一种标准化的方式来表示日期和时间,并且可以轻松地进行解析和比较

‘+’时间指示符
2024-06-10T16:21:29+08:00
这个时间格式是 ISO 8601 标准的一种变体,它包含了时区信息。

具体解释如下:

2024-06-10: 年-月-日
T: 时间开始的标识符
16:21:29: 时-分-秒
+08:00: 时区信息,表示当前时间比 UTC 时间早 8 个小时。
所以这个时间表示的是 2024 年 6 月 10 日 16 时 21 分 29 秒,对应的 UTC 时间是 2024 年 6 月 10 日 8 时 21 分 29 秒。

这种带有时区信息的 ISO 8601 时间格式非常有用,因为它可以准确地表示出特定时间点在不同时区的对应时间。

在 JavaScript 中,可以使用 new Date(‘2024-06-10T16:21:29+08:00’) 来创建一个 Date 对象,并获取相应的时间信息。

总之,这种时间格式包含了年月日、时分秒以及时区信息,可以更好地表示和处理跨时区的时间数据。

时间指示符

ISO 8601 时间格式中常见的时间指示符有以下几种:

T: 用于分隔日期和时间部分。例如 2023-04-24T15:30:00。

Z: 表示时间为 UTC (Coordinated Universal Time) 时间。例如 2023-04-24T15:30:00Z。

+/-: 用于表示时区。例如 2023-04-24T15:30:00+08:00 表示比 UTC 时间早 8 个小时。

.: 用于分隔秒和毫秒部分。例如 2023-04-24T15:30:00.123。

W: 用于表示周数。例如 2023-W17-1 表示 2023 年第 17 周的星期一。

D: 用于表示日期。例如 2023-04-24。

H: 用于表示小时。例如 15H30M00S。

M: 用于表示分钟。例如 15H30M00S。

S: 用于表示秒。例如 15H30M00S。

这些时间指示符可以根据需求灵活组合使用,以满足不同场景下的时间表示需求。比如 2023-04-24T15:30:00.123+08:00 就是一个包含了年月日、时分秒、毫秒和时区信息的完整 ISO 8601 时间格式。

date.getHours()//获取的是当地的时间

在 JavaScript 中,可以使用以下几种方式获取 YYYY-MM-DDTHH:mm:ss.000Z 格式的时间字符串:

//1.使用 new Date().toISOString()
const currentTime = new Date().toISOString();
console.log(currentTime); // 输出: "2023-04-24T15:30:00.000Z"
//2.使用 new Date().toJSON()
const currentTime = new Date().toJSON();
console.log(currentTime); // 输出: "2023-04-24T15:30:00.000Z"
//3.手动格式化 Date 对象
function formatDateTime(date) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
  return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`;
}

const currentTime = formatDateTime(new Date());
console.log(currentTime); // 输出: "2023-04-24T15:30:00.000Z"

//格式化日期

//下面是一个通用较高的自定义日期时间格式化函数的示例:
function formatDateTime(date, format) {
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, // 小时
    'H+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
    a: date.getHours() < 12 ? '上午' : '下午', // 上午/下午
    A: date.getHours() < 12 ? 'AM' : 'PM', // AM/PM
  };
  if (/(y+)/.test(format)) {
    format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      );
    }
  }
  return format;
}
//这个函数接受两个参数,第一个参数是要格式化的日期时间,可以是 Date 对象或表示日期时间的字符串,第二个参数是要格式化的格式,例如 yyyy-MM-dd HH:mm:ss。该函数会将日期时间格式化为指定的格式,并返回格式化后的字符串。

//该函数使用了正则表达式来匹配格式字符串中的占位符,然后根据对应的日期时间值来替换占位符。其中,y 会被替换为年份,M、d、h、H、m、s、q、S、a、A 分别表示月份、日期、小时(12 小时制)、小时(24 小时制)、分钟、秒、季度、毫秒、上午/下午、AM/PM。

//使用该函数进行日期时间格式化的示例如下:
const date = new Date();
console.log(formatDateTime(date, 'yyyy-MM-dd HH:mm:ss')); // 2023-02-16 08:25:05
console.log(formatDateTime(date, 'yyyy年MM月dd日 HH:mm:ss')); // 2023年02月16日 08:25:05
console.log(formatDateTime(date, 'yyyy-MM-dd HH:mm:ss S')); // 2023-02-16 08:25:05 950
console.log(formatDateTime(date, 'yyyy-MM-dd hh:mm:ss A')); // 2023-02-16 08:25:05 上午
//可以根据实际需要修改格式化的格式,以及支持更多的占位符和格式化选项。

点击查看csdn

let date= new Date()
date.getYear(); // 获取当前年份(2 位)
date.getFullYear(); // 获取完整的年份(4 位, 1970-????)
date.getMonth(); // 获取当前月份(0-11,0 代表 1 月)
date.getDate(); // 获取当前日(1-31)
date.getDay(); // 获取当前星期 X(0-6,0 代表星期天)
date.getTime(); // 获取当前时间(从 1970.1.1 开始的毫秒数)
date.getHours(); // 获取当前小时数(0-23)
date.getMinutes(); // 获取当前分钟数(0-59)
date.getSeconds(); // 获取当前秒数(0-59)
date.getMilliseconds(); // 获取当前毫秒数(0-999)
date.toLocaleDateString(); // 获取当前日期
date.toLocaleTimeString(); // 获取当前时间
date.toLocaleString( ); // 获取日期与时间

var date2 = new Date('2019-10-1 8:8:8')  //Tue Oct 01 2019 08:08:08 GMT+0800 (中国标准时间)
 date2.getTime()  //1569888488000

new Date可以传递参数
new Date传递参数


//优先记住,传递年月日
new Date("2022","01",0)
//Number可以把date日期转换成毫秒数
Number(new Date("2022","01",0))

获取当月的天数
csdn
setDate mdn

let date = new Date();
date.setMonth(date.getMonth() + 1); // 先设置为下个月
date.setDate(0); // 再置0,变成当前月最后一天
console.log(date.getDate()); // 当前月最后一天即当前月拥有的天数
//获取当前日期,格式YYYY-MM-DD
    function getNowFormatDay(nowDate) {
        var char = "-";
        if(nowDate == null){
            nowDate = new Date();
        }
        var day = nowDate.getDate();
        var month = nowDate.getMonth() + 1;//注意月份需要+1
        var year = nowDate.getFullYear();
        //补全0,并拼接
        return year + char + completeDate(month) + char +completeDate(day);
    }
 
    //获取当前时间,格式YYYY-MM-DD HH:mm:ss
    function getNowFormatTime() {
        var nowDate = new Date();
        var colon = ":";
        var h = nowDate.getHours();
        var m = nowDate.getMinutes();
        var s = nowDate.getSeconds();
        //补全0,并拼接
        return getNowFormatDay(nowDate) + " " + completeDate(h) + colon + completeDate(m) + colon + completeDate(s);
    }
 
    //补全0
    function completeDate(value) {
        return value < 10 ? "0"+value:value;
    }

三十八、JSON.parse(JSON.stringify())

点击查看缺陷
JSON.parse(JSON.stringify())只能用来深拷贝对象和数组,set,map不能,拷贝后是空对象
set,map深拷贝需要重构一下就行

const newSet = new Set(set)
const newMap = new Map(map)

JSON.parse(JSON.stringify())拷贝后的缺陷:
function ===》如果是对象会删除这个key和这个键,如果是数组,直接删除这个值
NaN ===》null
undefined ===》 空
时间戳 ===》字符串时间
错误信息 ===》 空对象
Infinity ===》null

三十九、获取url后参数

分为两种:

  1. 普通地址
  2. hash地址
    查看复制方法

四十、数组合并concat

注意是浅拷贝
参考点击

    const arr1 = [[1]]
    const arr2 = [3, 4]
    const arr3 = [5, 6]
    const arr4 = arr1.concat(arr2, arr3)
    console.log(arr4) // [[1], 3, 4, 5, 6]
    arr1[0].push(2)
    console.log(arr4) // [[1, 2], 3, 4, 5, 6]

四十一、代理函数

拦截大全
set拦截器:
1.对象添加属性走set
2.数组添加:
a:array[1]=2,走set,规范中明确说明,如果设置的索引值大于数组当前的
长度,那么要更新数组的 length 属性。所以当通过索引设置元素值
时,可能会隐式地修改 length 的属性值,但不会走length的set,(数组length会走length get ,set)
Reflect.set(target,key,receiver)后才会修改值和length
b:push走get和set,并且set 需要retrun true

ownKeys(target): for in 循环 Object.keys() (for in也会走Object.keys())

四十一、Object.getPrototypeOf()

proto 并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用 Object.getPrototypeOf() 方法来获取实例对象的原型,然后再来为原型添加方法/属性。

四十二、Object.getOwnPropertyNames()

带Own都不会获取原型上的属性
toString()方法是Point类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致。

var Point = function (x, y) {
  // ...
};

Point.prototype.toString = function () {
  // ...
};

Object.keys(Point.prototype)
// ["toString"]
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

上面代码采用 ES5 的写法,toString()方法就是可枚举的。

四十三、hasOwnProperty()

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var point = new Point(2, 3);

point.toString() // (2, 3)

point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true

上面代码中,x和y都是实例对象point自身的属性(因为定义在this对象上),所以hasOwnProperty()方法返回true,而toString()是原型对象的属性(因为定义在Point类上),所以hasOwnProperty()方法返回false。这些都与 ES5 的行为保持一致。

四十四、getOwnPropertyNames和keys

添加链接描述
区别
getOwnPropertyNames:返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。不包括原型

var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]

// 类数组对象
var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]

// 使用Array.forEach输出属性名和属性值
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// 输出
// 0 -> a
// 1 -> b
// 2 -> c

keys:返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。包含原型属性

// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

四十五、Object.keys()和Object.ownKeys()

相同点:都不可以获取不可枚举的属性
不同点:Object.keys()可以获取原型链上的属性,Object.ownKeys()获取对象自身的属性
Reflect.ownKeys()对应Object.keys(),Object.keys()暂无Reflect.keys()

四十六、in

添加链接描述
如果指定的属性(包括不可枚举)在指定的对象或其原型链中,则 in 运算符返回 true。
in右必须是个对象,数组和字符串对象需要使用索引,对象需要使用属性

var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // 返回 true
3 in trees        // 返回 true
6 in trees        // 返回 false
"bay" in trees    // 返回 false (必须使用索引号,而不是数组元素的值)

var color1 = new String("green");
"length" in color1 // 返回 true
var color2 = "coral";
"length" in color2 // 报错 (color2 不是对象)
console.log(1 in color1); //true
console.log(100 in color1); //false

const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car);
// Expected output: true

四十七、Number

NaN:Number.NaN
Number.isNaN():可以判断是否是一个NaN(注意:NaN和NaN不相等)
在这里插入图片描述

四十八、Object.defineProperty

添加链接描述
Object.defineProperty常用来代理
那该方法的第三个参数除了可以是数据属性,也可以是访问器属性,两种属性不能同时存在

1.代理属性

   let obj ={
            a:3
        }
        Object.defineProperty(obj,'b',{
            value:5,
            enumerable:false,
        })
        Object.defineProperty(obj,'c',{
            get:function(){
                return obj.a
            },
            set(val){
                obj.a=val
            }
        })
        obj.c=10
        console.log("obj.a",obj.a);

2.设置属性

  let obj ={
            a:3
        }
   Object.defineProperty(obj,'b',{
        value:5,
        //枚举,删除权限全是false,即是默认不能删除和枚举
        enumerable:false,
   })
    console.log(obj.b);
        for (const key in obj) {
            console.log("forin",obj[key]); //3
        }

四十九、\ 转义符

添加链接描述
反斜杠(\)在!!!字符串!!!内有特殊含义,用来表示一些特殊字符,所以又称为转义符,字符串中有正则特殊的字符\w(字符) \d(数字) .(几乎所有字符)等等都是有特殊含义的,需要转义

在正则中没有特殊含义,如果在正则中使用 \ , . 表示的是.字符而不是所有的字符类型

//   /在字符串中
v+=`<tr > 
				<td >
							<input type="text" oninput="value=value.replace(/[^\\d\\.]/g,'')" class="form-control readonly_one" 				
							${e.business_promotion==0?'readonly':''} value=${e.show_amount} name="attrs[${i}][show_amount]">
				</td>
	`
//   /w标识数字和字母  不能写成 //w
let regex=/#\w{1,}/g

五十、“” ‘’

双引号内只能使用单引号,反之依然,内引号会被显示出来

let utl=2
let utl2=3
//<div class="hang" data-units="2
let str= '<div class="hang" data-units="'+utl

//补全2的引号
//<div class="hang" data-units="2"
let str= '<div class="hang" data-units="'+utl+'"'

五十一、fill

添加链接描述

//如果value是引用的,则添加的都是同一个value
fill(value)
fill(value, start)
fill(value, start, end)

问题
添加链接描述

五十二、Array.from()

添加链接描述
Array.from(arrayLike,mapFn,thisArg)
arrayLike:必选,想要转换成数组的伪数组对象或可迭代对象
mapFn:可选,如果指定了该参数,新数组中的每个元素会执行该函数
thisArg:可选,执行回调函数mapFn时this对象
可迭代的对象包括ES6新增的数据结构Set和Map

Array.from可以通过以下方式来创建数组对象
	1. 伪数组(拥有一个length属性和若干索引属性的任意对象)
	2. 可迭代对象(可以获取对象中的元素,如Map和Set等)
Array.from()方法有一个可选参数mapFn,让你可以在最后生成的数组上,再执行一次map方法后再返回。
即Array.from(obj,mapFn,thisArg)相当于Array.from(obj).map(mapFn,thisArg);
let likeArr  = {
            0:'react',
            1:'Vue',
            2:'angular',
            3:'Node',
            'length':4
        }
let arr = Array.from(likeArr,function (item){return item+this.b},{b:2})     
 console.log(arr)

在这里插入图片描述

五十四、编码和解码

添加链接描述
在这里插入图片描述

五十五、获取ip地址或省份和城市

添加链接描述
添加链接描述

<body>
 <script>
    function ipJson(ipJson) {
      console.log('获取到的网络IP',ipJson);
      //可以把结果存在window上,方便调用
      window.ipJson=ipJson;
    }
  </script>
  <script src="//whois.pconline.com.cn/ipJson.jsp?callback=ipJson" type="text/javascript"></script>
</body>

报403:原因分析:Referer携带了我们自身网站的域名,第三方网站认为这是非法访问,所以报错403 forbidden,因此我们需要在自己项目中访问第三方外链的时候,去掉Referer信息:

//头部加个标签
<meta name="referrer" content="no-referrer" />

五十六、blob

添加链接描述

五十七、判断数据类型

let a = [1,2]
Object.prototype.toString.call(a)  // '[object Array]'   

let c=''
Object.prototype.toString.call(c) //'[object String]'

let dd={}
Object.prototype.toString.call(dd) //'[object Object]'

let d = 2
Object.prototype.toString.call(d) //'[object Number]'
Object.prototype.toString.call(d) == '[object Number]' //true

五十八、小数向上进1

//直接向上进1保留两位小数
Math.ceil((100.663)*100)/100
 
//保留两位小数,四舍五入
Math.round((parseFloat(100.365) + parseFloat(369.369))*100)/100;
 
直接保留两位
var price = 6.3656
price.toFixed(2)  //保留两位小数

五十九、复制

添加链接描述

 function copy2(content) {
        const dom = document.createElement("input");
        dom.value = content;
        document.body.appendChild(dom);
        dom.select();
        document.execCommand("copy");
        document.body.removeChild(dom);
      }

六十、获取各种高度和宽度

获取高度和宽度

六十一、判断点击在dom外

 window.addEventListener('click', (e) => { 
        var elem = e.target;
        var targetArea = document.querySelector('.bottom');
        if(!targetArea.contains(elem)){

          }
      })

六十二、打印dom

打印dom出现的是元素而非dom对象,实际是dom对象。
打印看可以放在数组里面
添加链接描述

六十三、组件时间差问题

添加链接描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值