【ES6】数值扩展/箭头函数及/::

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()方法的区别,传统的这两个方法,是先将参数转换成数值,再判断。
而ES6新增的这两个方法则只对数值有效, 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()一致,目的是逐步减少全局性的方法,让语言更??榛?/strong>。

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():
    用于返回一个数的 32 位无符号整数形式有多少个前导 0。
Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1000) // 22
Math.clz32(0b01000000000000000000000000000000) // 1
Math.clz32(0b00100000000000000000000000000000) // 2

  • Math.imul():
    用于返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。
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

注意:

  • 参数变量是默认声明的,不能用letconst再次声明:
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 双冒号运算符

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

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

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

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

let f = a::a.b;
// 等同于
let f = ::a.b;
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容

  • [TOC] 参考阮一峰的ECMAScript 6 入门参考深入浅出ES6 let和const let和const都...
    郭子web阅读 1,777评论 0 1
  • 1. 二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)...
    焦迈奇阅读 347评论 0 0
  • 前面的话 在ES5中,我们存在几个全局函数isNaN函数,isFinite函数,parseInt函数,parseF...
    CodeMT阅读 406评论 0 0
  • 此文包含数值的扩展、函数的扩展,总结了一些我认为有可能会用到的,而去除了一些稍稍复杂一时难以去学习理解且目前不想去...
    六个周阅读 543评论 0 7
  • 二进制和八进制表示法 ES6提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。 从...
    陈老板_阅读 485评论 0 1