重温基础:ES6系列(二)

640?wx_fmt=png

ES6系列目录

  • 1 let 和 const命令

  • 2 变量的解构赋值

  • 3 字符串的拓展

  • 4 正则的拓展

  • 数值的拓展

  • 函数的拓展

  • 数组的拓展

  • 8 对象的拓展

  • 9 Symbol

  • 10 Set和Map数据结构

  • 11 Proxy

  • 12 Promise对象

  • 13 Iterator和 for...of循环

  • 14 Generator函数和应用

  • 15 Class语法和继承

  • 16 Module语法和加载实现

所有整理的文章都收录到我《Cute-JavaScript》系列文章中,访问地址:http://js.pingan8787.com

5 数值的拓展

5.1 Number.isFinite(), Number.isNaN()

Number.isFinite() 用于检查一个数值是否是有限的,即不是 Infinity,若参数不是 Number类型,则一律返回 false

Number.isFinite(10);            // true	
Number.isFinite(0.5);           // true	
Number.isFinite(NaN);           // false	
Number.isFinite(Infinity);      // false	
Number.isFinite(-Infinity);     // false	
Number.isFinite('leo');         // false	
Number.isFinite('15');          // false	
Number.isFinite(true);          // false	
Number.isFinite(Math.random()); // true

Number.isNaN()用于检查是否是 NaN,若参数不是 NaN,则一律返回 false

Number.isNaN(NaN);      // true	
Number.isNaN(10);       // false	
Number.isNaN('10');     // false	
Number.isNaN(true);     // false	
Number.isNaN(5/NaN);    // true	
Number.isNaN('true' / 0);      // true	
Number.isNaN('true' / 'true'); // true

区别isFinite()isNaN()方法的区别,传统的这两个方法,是先将参数转换成数值,再判断。数值有效, Number.isFinite()对于非数值一律返回 false, Number.isNaN()只有对于 NaN才返回 true,其他一律返回 false

isFinite(25);          // true	
isFinite("25");        // true	
Number.isFinite(25);   // true	
Number.isFinite("25"); // false	
isNaN(NaN);            // true	
isNaN("NaN");          // true	
Number.isNaN(NaN);     // true	
Number.isNaN("NaN");   // false

5.2 Number.parseInt(), Number.parseFloat()

这两个方法与全局方法 parseInt()parseFloat()一致,目的是逐步减少全局性的方法,让语言更模块化

parseInt('12.34');     // 12	
parseFloat('123.45#'); // 123.45	
Number.parseInt('12.34');     // 12	
Number.parseFloat('123.45#'); // 123.45	
Number.parseInt === parseInt;     // true	
Number.parseFloat === parseFloat; // true

5.3 Number.isInteger()

用来判断一个数值是否是整数,若参数不是数值,则返回 false

Number.isInteger(10);   // true	
Number.isInteger(10.0); // true	
Number.isInteger(10.1); // false

5.4 Math对象的拓展

ES6新增17个数学相关的静态方法,只能在Math对象上调用。

  • Math.trunc:返回整数部分非数值,则先转为数值空值无法截取整数的值,则返回NaN

// 正常使用	
Math.trunc(1.1);     // 1	
Math.trunc(1.9);     // 1	
Math.trunc(-1.1);    // -1	
Math.trunc(-1.9);    // -1	
Math.trunc(-0.1234); // -0	
// 参数为非数值	
Math.trunc('11.22'); // 11	
Math.trunc(true);    // 1	
Math.trunc(false);   // 0	
Math.trunc(null);    // 0	
// 参数为空和无法取整	
Math.trunc(NaN);       // NaN	
Math.trunc('leo');     // NaN	
Math.trunc();          // NaN	
Math.trunc(undefined); // NaN

ES5实现

Math.trunc = Math.trunc || function(x){	
    return x < 0 ? Math.ceil(x) : Math.floor(x);	
}
  • Math.sign():正数负数是零,对于非数值,会先转成数值

    • 参数为正数, 返回 +1

    • 参数为负数, 返回 -1

    • 参数为0, 返回 0

    • 参数为-0, 返回 -0

    • 参数为其他值, 返回 NaN

Math.sign(-1);   // -1	
Math.sign(1);    // +1	
Math.sign(0);    // 0	
Math.sign(-0);   // -0	
Math.sign(NaN);  // NaN	
Math.sign('');   // 0	
Math.sign(true); // +1	
Math.sign(false);// 0	
Math.sign(null); // 0	
Math.sign('9');  // +1	
Math.sign('leo');// NaN	
Math.sign();     // NaN	
Math.sign(undefined); // NaN

ES5实现

Math.sign = Math.sign || function (x){	
    x = +x;	
    if (x === 0 || isNaN(x)){	
        return x;	
    }	
    return x > 0 ? 1: -1;	
}
  • Math.cbrt():

Math.cbrt(-1); // -1	
Math.cbrt(0);  // 0	
Math.cbrt(1);  // 1	
Math.cbrt(2);  // 1.2599210498	
Math.cbrt('1');   // 1	
Math.cbrt('leo'); // NaN

ES5实现

Math.cbrt = Math.cbrt || function (x){	
    var a = Math.pow(Math.abs(x), 1/3);	
    return x < 0 ? -y : y;	
}
  • Math.clz32():

Math.clz32(0) // 32	
Math.clz32(1) // 31	
Math.clz32(1000) // 22	
Math.clz32(0b01000000000000000000000000000000) // 1	
Math.clz32(0b00100000000000000000000000000000) // 2
  • Math.imul():

Math.imul(2, 4)   // 8	
Math.imul(-1, 8)  // -8	
Math.imul(-2, -2) // 4
  • Math.fround():2位单精度浮点数形式。

Math.fround(0)   // 0	
Math.fround(1)   // 1	
Math.fround(2 ** 24 - 1)   // 16777215
  • Math.hypot():平方根

Math.hypot(3, 4);        // 5	
Math.hypot(3, 4, 5);     // 7.0710678118654755	
Math.hypot();            // 0	
Math.hypot(NaN);         // NaN	
Math.hypot(3, 4, 'foo'); // NaN	
Math.hypot(3, 4, '5');   // 7.0710678118654755	
Math.hypot(-3);          // 3
  • Math.expm1():ex-1,即 Math.exp(x)-1

Math.expm1(-1) // -0.6321205588285577	
Math.expm1(0)  // 0	
Math.expm1(1)  // 1.718281828459045

ES5实现

Math.expm1 = Math.expm1 || function(x) {	
  return Math.exp(x) - 1;	
};
  • Math.log1p():1+x的自然对数,即 Math.log(1+x)。如果x小于 -1,返回 NaN

Math.log1p(1)  // 0.6931471805599453	
Math.log1p(0)  // 0	
Math.log1p(-1) // -Infinity	
Math.log1p(-2) // NaN

ES5实现

Math.log1p = Math.log1p || function(x) {	
  return Math.log(1 + x);	
};
  • Math.log10():10为底的 x的对数。如果x小于 0,则返回 NaN

Math.log10(2)      // 0.3010299956639812	
Math.log10(1)      // 0	
Math.log10(0)      // -Infinity	
Math.log10(-2)     // NaN	
Math.log10(100000) // 5

ES5实现

Math.log10 = Math.log10 || function(x) {	
  return Math.log(x) / Math.LN10;	
};
  • Math.log2():2 为底的 x的对数。如果 x小于 0,则返回 NaN

Math.log2(3)       // 1.584962500721156	
Math.log2(2)       // 1	
Math.log2(1)       // 0	
Math.log2(0)       // -Infinity	
Math.log2(-2)      // NaN	
Math.log2(1024)    // 10	
Math.log2(1 << 29) // 29

ES5实现

Math.log2 = Math.log2 || function(x) {	
  return Math.log(x) / Math.LN2;	
};
  • 双曲函数方法:

    • Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)

    • Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)

    • Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)

    • Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)

    • Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)

    • Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

5.5 指数运算符

新增的指数运算符( **):

2 ** 2; // 4	
2 ** 3; // 8 	
2 ** 3 ** 2; // 相当于 2 ** (3 ** 2); 返回 512

指数运算符( **)与 Math.pow的实现不相同,对于特别大的运算结果,两者会有细微的差异。

Math.pow(99, 99)	
// 3.697296376497263e+197	
99 ** 99	
// 3.697296376497268e+197

6 函数的拓展

6.1 参数默认值

// ES6 之前	
function f(a, b){	
    b = b || 'leo';	
    console.log(a, b);	
}	
// ES6 之后	
function f(a, b='leo'){	
    console.log(a, b);	
}	
f('hi');          // hi leo	
f('hi', 'jack');  // hi jack	
f('hi', '');      // hi leo

注意:

  • 参数变量是默认声明的,不能用 let和 const再次声明:

function f (a = 1){	
    let a = 2; // error	
}
  • 使用参数默认值时,参数名不能相同:

function f (a, a, b){ ... };     // 不报错	
function f (a, a, b = 1){ ... }; // 报错

与解构赋值默认值结合使用

function f ({a, b=1}){	
    console.log(a,b)	
};	
f({});         // undefined 1	
f({a:2});      // 2 1	
f({a:2, b:3}); // 2 3	
f();           // 报错	
function f ({a, b = 1} = {}){	
    console.log(a, b)	
}	
f();  // undefined 1

尾参数定义默认值:

function f (a=1,b){	
    return [a, b];	
}	
f();    // [1, undefined]	
f(2);   // [2, undefined]	
f(,2);  // 报错	
f(undefined, 2);  // [1, 2]	
function f (a, b=1, c){	
    return [a, b, c];	
}	
f();        // [undefined, 1, undefined]	
f(1);       // [1,1,undefined]	
f(1, ,2);   // 报错	
f(1,undefined,2); // [1,1,2]

在给参数传递默认值时,传入 undefined会触发默认值,传入 null不会触发。

function f (a = 1, b = 2){	
    console.log(a, b);	
}	
f(undefined, null); // 1 null

函数的length属性:length属性将返回,没有指定默认值的参数数量,并且rest参数不计入 length属性。

function f1 (a){...};	
function f2 (a=1){...};	
function f3 (a, b=2){...};	
function f4 (...a){...};	
function f5 (a,b,...c){...};	
f1.length; // 1	
f2.length; // 0	
f3.length; // 1	
f4.length; // 0	
f5.length; // 2

6.2 rest 参数

rest参数形式为( ...变量名),其值为一个数组,用于获取函数多余参数。

function f (a, ...b){	
    console.log(a, b);	
}	
f(1,2,3,4); // 1 [2, 3, 4]

注意

  • rest参数只能放在最后一个,否则报错:

function f(a, ...b, c){...}; // 报错 
  • 函数的 length属性不包含 rest参数。

function f1 (a){...};	
function f2 (a,...b){...};	
f1(1);   // 1	
f2(1,2); // 1

6.3 name 属性

用于返回该函数的函数名。

function f (){...};	
f.name;    // f	
const f = function g(){...};	
f.name;    // g

6.4 箭头函数

使用“箭头”( =>)定义函数。基础使用

// 有1个参数	
let f = v => v;	
// 等同于	
let f = function (v){return v};	
// 有多个参数	
let f = (v, i) => {return v + i};	
// 等同于	
let f = function (v, i){return v + i};	
// 没参数	
let f = () => 1;	
// 等同于	
let f = function (){return 1};

箭头函数与变量结构结合使用

// 正常函数写法	
function f (p) {	
    return p.a + ':' + p.b;	
}	
// 箭头函数写法	
let f = ({a, b}) => a + ':' + b;

简化回调函数

// 正常函数写法	
[1, 2, 3].map(function (x){	
    return x * x;	
})	
// 箭头函数写法	
[1, 2, 3].map(x => x * x);

箭头函数与rest参数结合

let f = (...n) => n;	
f(1, 2, 3); // [1, 2, 3]

注意点

  • 1.箭头函数内的 this总是指向定义时所在的对象,而不是调用时。

  • 2.箭头函数不能当做构造函数,即不能用 new命令,否则报错。

  • 3.箭头函数不存在 arguments对象,即不能使用,可以使用 rest参数代替。

  • 4.箭头函数不能使用 yield命令,即不能用作Generator函数。

不适用场景

  • 1.在定义函数方法,且该方法内部包含 this

const obj = {	
    a:9,	
    b: () => {	
        this.a --;	
    }	
}

上述 b如果是普通函数,函数内部的 this指向 obj,但是如果是箭头函数,则 this会指向全局,不是预期结果。

  • 2.需要动态 this时。

let b = document.getElementById('myID');	
b.addEventListener('click', ()=>{	
    this.classList.toggle('on');	
})

上诉按钮点击会报错,因为 b监听的箭头函数中, this是全局对象,若改成普通函数this就会指向被点击的按钮对象。

6.5 双冒号运算符

双冒号暂时是一个提案,用于解决一些不适用的场合,取代 callapplybind调用。::)的左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即 this对象),绑定到右边函数上。

f::b;	
// 等同于	
b.bind(f);	
f::b(...arguments);	
// 等同于	
b.apply(f, arguments);

若双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定到该对象上。

let f = a::a.b;	
// 等同于	
let f = ::a.b;

7 数组的拓展

7.1 拓展运算符

拓展运算符使用( ...),类似 rest参数的逆运算,将数组转为用( ,)分隔的参数序列。

console.log(...[1, 2, 3]);   // 1 2 3 	
console.log(1, ...[2,3], 4); // 1 2 3 4

拓展运算符主要使用在函数调用。

function f (a, b){	
    console.log(a, b);	
}	
f(...[1, 2]); // 1 2	
function g (a, b, c, d, e){	
    console.log(a, b, c, d, e);	
}	
g(0, ...[1, 2], 3, ...[4]); // 0 1 2 3 4

若拓展运算符后面是个空数组,则不产生效果

[...[], 1]; // [1]

替代apply方法

// ES6之前	
function f(a, b, c){...};	
var a = [1, 2, 3];	
f.apply(null, a);	
// ES6之后	
function f(a, b, c){...};	
let a = [1, 2, 3];	
f(...a);	
// ES6之前	
Math.max.apply(null, [3,2,6]);	
// ES6之后	
Math.max(...[3,2,6]);

拓展运算符的运用

  • (1)复制数组

// 通常情况 浅拷贝	
let a1 = [1, 2];	
let a2 = a1; 	
a2[0] = 3;	
console.log(a1,a2); // [3,2] [3,2]	
// 拓展运算符 深拷贝	
let a1 = [1, 2];	
let a2 = [...a1];	
// let [...a2] = a1; // 作用相同	
a2[0] = 3;	
console.log(a1,a2); // [1,2] [3,2]
  • (2)合并数组

let a1 = [1,2];	
let a2 = [3];	
let a3 = [4,5];	
// ES5 	
let a4 = a1.concat(a2, a3);	
// ES6	
let a5 = [...a1, ...a2, ...a3];	
a4[0] === a1[0]; // true	
a5[0] === a1[0]; // true
  • (3)与解构赋值结合

let [a, ...b] = [1, 2, 3, 4]; 	
// a => 1  b => [2,3,4]	
let [a, ...b] = [];	
// a => undefined b => []	
let [a, ...b] = ["abc"];	
// a => "abc"  b => []

7.2 Array.from()

类数组对象可遍历的对象,转换成真正的数组。

// 类数组对象	
let a = {	
    '0':'a',	
    '1':'b',	
    length:2	
}	
let arr = Array.from(a);	
// 可遍历的对象	
let a = Array.from([1,2,3]);	
let b = Array.from({length: 3});	
let c = Array.from([1,2,3]).map(x => x * x);	
let d = Array.from([1,2,3].map(x => x * x));

7.3 Array.of()

将一组数值,转换成数组,弥补 Array方法参数不同导致的差异。

Array.of(1,2,3);    // [1,2,3]	
Array.of(1).length; // 1	
Array();       // []	
Array(2);      // [,] 1个参数时,为指定数组长度	
Array(1,2,3);  // [1,2,3] 多于2个参数,组成新数组

7.4 find()和findIndex()

find()方法用于找出第一个符合条件的数组成员,参数为一个回调函数,所有成员依次执行该回调函数,返回第一个返回值为 true的成员,如果没有一个符合则返回 undefined

[1,2,3,4,5].find( a => a < 3 ); // 1

回调函数接收三个参数,当前值、当前位置和原数组。

[1,2,3,4,5].find((value, index, arr) => {	
    // ...	
});

findIndex()方法与 find()类似,返回第一个符合条件的数组成员的位置,如果都不符合则返回 -1

[1,2,3,4].findIndex((v,i,a)=>{	
    return v>2;	
}); // 2

7.5 fill()

用于用指定值填充一个数组,通常用来初始化空数组,并抹去数组中已有的元素。

new Array(3).fill('a');   // ['a','a','a']	
[1,2,3].fill('a');        // ['a','a','a']

并且 fill()的第二个和第三个参数指定填充的起始位置结束位置

[1,2,3].fill('a',1,2);//  [1, "a", 3]

7.6 entries(),keys(),values()

主要用于遍历数组, entries()对键值对遍历, keys()对键名遍历, values()对键值遍历。

for (let i of ['a', 'b'].keys()){	
    console.log(i)	
}	
// 0	
// 1	
for (let e of ['a', 'b'].values()){	
    console.log(e)	
}	
// 'a'	
// 'b'	
for (let e of ['a', 'b'].entries()){	
    console.log(e)	
}	
// 0 'a'	
// 1 'b'

7.7 includes()

用于表示数组是否包含给定的值,与字符串的 includes方法类似。

[1,2,3].includes(2);     // true	
[1,2,3].includes(4);     // false	
[1,2,NaN].includes(NaN); // true

第二个参数为起始位置,默认为 0,如果负数,则表示倒数的位置,如果大于数组长度,则重置为 0开始。

[1,2,3].includes(3,3);    // false	
[1,2,3].includes(3,4);    // false	
[1,2,3].includes(3,-1);   // true	
[1,2,3].includes(3,-4);   // true

7.8 flat(),flatMap()

flat()用于将数组一维化,返回一个新数组,不影响原数组。Infinity作为参数。

[1, 2, [2,3]].flat();        // [1,2,2,3]	
[1,2,[3,[4,[5,6]]]].flat(3); // [1,2,3,4,5,6]	
[1,2,[3,[4,[5,6]]]].flat('Infinity'); // [1,2,3,4,5,6]

flatMap()是将原数组每个对象先执行一个函数,在对返回值组成的数组执行 flat()方法,返回一个新数组,不改变原数组。flatMap()只能展开一层。

[2, 3, 4].flatMap((x) => [x, x * 2]); 	
// [2, 4, 3, 6, 4, 8] 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值