你可能从未使用过的11+个JavaScript特性(小结)


Posted in Javascript onJanuary 08, 2020

重要

这篇文章中描述的大多数功能已被暂停使用(甚至不推荐使用)。 它们仍然在许多图书中很常见,因此值得学习。

一、逗号运算符

, 是用于分隔表达式并返回链中最后一个表达式的运算符。

let oo = (1, 2, 3)
console.log(oo) // 3

这里有三个主要表达式 1 、 2 和 3。所有这些表达式均被求值,最后一个赋给 oo。

我们在 for 循环中看到这个:

for(let i = 0, ii = 1; i< 10; i++, ii--) { ... }

当我们要编写短的 lambda 函数时,这会派上用场:

const lb = (a, b, arr) => (arr.push(a*b), a*b)

这里有两个语句,第一个将乘法结果推入数组arr,第二个将乘数a和b推入数组。 第二个结果就是返回给调用者的内容。

对于三元运算符,它也很有用,因为与短lambda语法相同,它仅接受表达式而不是语句。

二、in

in 是用于检查对象中属性是否存在的关键字。 我们在 for..in 循环中使用了它,但没有意识到,其实 in 也是一个关键字:)
如果对象上存在属性,则 in 将返回 true ,否则将返回 false。

const o = {
  prop: 1
}
console.log("prop" in o) // true

看,in 可以独立使用,而不是在 for..in 中。

它将检查 "prop" 是否可作为 o 对象中的属性使用。 它返回 true ,因为我们在 o 中定义了 "prop" 属性。

如果我们检查未定义的属性:

const o = {
  prop: 1
}
console.log("prop1" in o) // false

它返回 false ,因为 "prop1" 在 o 中未定义。

三、Array 构造函数

你知道我们可以不使用传统方法定义数组吗?

const arr = [1, 2, 3]

怎么样?

我们也可以使用 Array :

const arr = new Array(1, 2, 3)

传递给 Array 构造函数的参数的排列将构成其索引的基础。

1 是第一个参数,其索引为 0; 2 是第二个参数,其索引为 1; 3 是第三个参数,其索引为 2。

arr[0] // 1
arr[1] // 2
arr[2] // 3

所以,

const arr = new Array(1, 2, 3)


const arr = [1, 2, 3]

表达的是一个意思。

但使用 new Array() 有一个问题,例如:

var a = new Array(10, 20);
a[0] // 返回 10
a.length // 返回 2

但:

var a = new Array(10);
a[0] // 返回 undefined
a.length // 返回 10

当你仅给 Array 构造函数一个整数(大于等于 0 的整数,否则将会报错)时,才会发生这种情况。 这是为什么喃?

其实,新的 Array 构造函数正在从某些编程语言中提取思想,在这些语言中,你需要为数组指定内存,这样就不会出现 ArrayIndexOutOfBounds 异常。

int *a = (int *) malloc( 10*sizeof(int) ); // ya ol' c
int *a = new int[10]; // c++
int[] a = new int[10]; // java

是的,它实际上是在创建一个长度为 10 的数组。我们在 Javascript 中没有 sizeof 函数,但是 toString 足以证明这一点。

a.toString() // 返回 ",,,,,,,,," 它相当于 [,,,,,,,,,]
a // [empty × 10]

所以,当将一个参数传递给的 new Array,将导致 JS 引擎为传递的参数大小的数组分配空间。

并且这也在 EcmaScript 规范中:

你可能从未使用过的11+个JavaScript特性(小结)

看,这不是矛盾的。 规格中都有所有描述。 在得出任何结论之前,我们应该始终先阅读任何语言的规范。

四、Function 构造函数

你是否知道我们可以使用 Function 构造函数定义 Function 。

你不明白吧? 让我更清楚。 在 JavaScript 中,我们定义如下函数:

const mul = (a, b) => a * b

// 或
function mul(a, b) {
  return a * b
}

// 或
const mul = function(a, b) {
  return a * b
}

我们也可以这样做,来实现相同的功能:

const mul = new Function("a", "b", "return a * b")

传递给 Function 的参数形成函数的参数和主体。 变量 mul 成为函数名称。

并且,最后一个参数将是函数的主体,而最后一个参数之前的参数将成为函数的参数。

在在 mul 中。  "a" 和 "b" 是函数将接收的参数,"return a * b" 是函数的主体。 它实现将 "a" 和 "b" 相乘并返回结果。

我们使用 mul(…) 调用该函数,并传入参数:

const mul = new Function("a", "b", "return a * b")

console.log(mul(7, 8)) // 56

根据 MDN:

Function 构造函数创建一个新的 Function 对象。直接调用此构造函数可用动态创建函数,但会遭遇来自 eval 的安全问题和相对较小的性能问题。然而,与 eval 不同的是,Function 构造函数只在全局作用域中运行。

五、数组解构

我们可以通过使用元素的索引号来分解数组中的元素。

const arr = [1, 2, 3]

元素 1 、2 、3 的索引分别为 0、1、2,即:

arr[0] // 1

在日常开发中,我们最常使用的是对象解构:

let o = {
  prop: 1
}
o["prop"] // 1

// 解构
const {prop} = o
prop // 1

所以,我们将解构用于数组上:

const arr = [1, 2, 3]
const { 0: firstA, 1: secA, 2: thirdA } = arr

firstA // 1
secA // 2
thirdA // 3

所以我们可以使用索引号来提取元素。索引是定义数组中元素位置的属性。

const arr = [1, 2, 3]

相当于:

const arr = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
}

数组也是对象,这就是为什么要对其进行对象分解的原因,但是还有一种特殊的数组分解语法:

const [first, second, third] = arr

first // 1
second // 2
third // 3

注意:应尽可能避免知道数组中的特定位置信息(开始、结束索引是什么)。

六、使用 length 属性减少数组内容

数组中的 length 属性表示数组中元素的数目。

const arr = [1, 2, 3]
arr.length // 3

减小 length 属性值,会使 JS 引擎将数组元素个数减少到与 length 属性的值相等。

const arr = [1, 2, 3]
arr.length // 3
arr.length = 1
arr // [1]

arr 的 length 属性值更改为 1,因此 arr 减少了元素个数,使其等于 length 属性值。

如果增加 length 属性,则 JS 引擎将添加元素(未定义的元素)以使数组中的元素数量达到 length 属性的值。

const arr = [1, 2, 3]
arr.length // 3
arr.length = 1
arr // [1]

arr.length = 5
arr // [1, empty × 4]

arr 中的元素只有一个,然后我们将长度增加到 5 ,因此又增加了 4 个元素长度,使元素数达到 5。

七、Arguments

我们可以使用 arguments 对象获取传递给函数的参数,而无需在函数中明确定义 arguments 变量:

function myFunc() {
  console.log(arguments[0]) // 34
  console.log(arguments[1]) // 89
}

myFunc(34,89)

arguments 对象是数组索引的。 也就是说,属性是数字,因此可以通过键引用进行访问。

arguments 对象是从 Arguments 类实例化的,该类具有一些很酷的属性。

arguments.callee.name 指当前正在调用的函数的名称。

function myFunc() {
  console.log(arguments.callee.name) // myFunc
}

myFunc(34, 89)

arguments.callee.caller.name 是指调用当前执行函数的函数的名称。

function myFunc() {
  console.log(arguments.callee.name) // myFunc
  console.log(arguments.callee.caller.name) // myFuncCallee
}

(function myFuncCallee() {
  myFunc(34, 89)
})()

这在可变参数功能中特别有用。

八、跳过 ()

你是否知道实例化对象时可以跳过方括号 () ?

例如:

class D {
  logger() {
    console.log("D")
  }
}

// 一般情况下,我们这么做:
(new D()).logger(); // D

// 其实,我们可以跳过 ():
(new D).logger(); // D
// 并且它可以正常运行

即使在内置类中,括号也是可选的:

(new Date).getDay();
(new Date).getMonth();
(new Date).getYear();

九、void

void 是 JS 中的关键字,用于评估语句并返回未定义。

例如:

class D {
  logger() {
    return 89
  }
}

const d = new D

console.log(void d.logger()) // undefined

logger 方法应该返回 89 ,但是 void 关键字将使其无效并返回 undefined 。

我曾经读到过 undefined 之前可能会被赋予另一个值,而这会伪造其语义。 因此,使用 void 运算符可确保你得到一个真正的 undefined 。 也用于最小化目的。

十、通过 __proto__ 继承

_proto_ 是从 JavaScript 中的对象继承属性的方法。 __proto__ 是   Object.prototype 的访问器属性,它公开访问对象的 [[Prototype]] 。

此 __proto__ 将其 [[Prototype]] 中设置的对象的所有属性设置为目标对象。

让我们看一个例子:

const l = console.log
const obj = {
  method: function() {
    l("method in obj")
  }
}
const obj2 = {}
obj2.__proto__ = obj
obj2.method() // method in obj

我们有两个对象常量: obj 和 obj2 。 obj 具有 method 属性。 obj2 是一个空的对象常量,即它没有属性。

我们访问 obj2 的 __proto__ 并将其设置为 obj 。 这会将通过 Object.prototype 可访问的 obj 的所有属性复制到 obj2 。 这就是为什么我们可以在 obj2 上调用方法而不会在没有定义的情况下得到错误的原因。

obj2 继承了 obj 的属性,因此 method 方法属性将在其属性中可用。

原型可用于对象,例如对象常量、对象、数组、函数、日期、RegEx、数字、布尔值、字符串。

十一、一元运算符 +

一元 + 运算符将其操作数转换为数字类型。

+"23" // 23
+{} // NaN
+null // 0
+undefined // NaN
+{ valueOf: () => 67 } // 67
+"nnamdi45" // NaN

当我们希望将变量快速转换为 Number 时,这非常方便。

十二、一元运算符 -

一元运算符 - 将其操作数转换为 Number 类型,然后取反。

该运算符将一元 + 运算符的结果取反。 首先,它将操作数转换为其 Number 值,然后取反该值。

-"23" // -23

此处发生的是,字符串 "23" 将转换为其数字类型,从而得到 23 。然后,此正数将转换为其负数形式 -23 。

-{} // NaN
-null // -0
-undefined // NaN
-{ valueOf: () => 67 } // -67
-"nnamdi45" // NaN

如果转换为数值的结果为 NaN ,则不会应用取反。

取负 +0 产生 -0 ,取负 -0 产生 +0 。

- +0 // -0
- -0 // 0

十三、指数运算符 **

该运算符用于指定数字的指数。

在数学中, 2^3^ 意味着将 2 乘以三次:

2 * 2 * 2

我们可以使用 ** 运算符在 JS 中进行相同的操作:

2 ** 3 // 8
9 ** 3 // 729

总结

本文翻译自 11+ JavaScript Features You've Probably Never Used

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 文件引入实现代码
Apr 23 Javascript
JS判断页面加载状态以及添加遮罩和缓冲动画的代码
Oct 11 Javascript
Jquery 动态循环输出表格具体方法
Nov 23 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
Jan 23 Javascript
js统计页面的来访次数实现代码
May 09 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
Aug 30 Javascript
Angularjs手动解析表达式($parse)
Oct 12 Javascript
JS 全屏和退出全屏详解及实例代码
Nov 07 Javascript
JS全角与半角转化实例(分享)
Jul 04 Javascript
vue+elementui 对话框取消 表单验证重置示例
Oct 29 Javascript
Vue 中 filter 与 computed 的区别与用法解析
Nov 21 Javascript
JavaScript与JQuery框架基础入门教程
Jul 15 Javascript
你知道JavaScript Symbol类型怎么用吗
Jan 08 #Javascript
js实现多个标题吸顶效果
Jan 08 #Javascript
Vue v-model组件封装(类似弹窗组件)
Jan 08 #Javascript
jquery实现吸顶导航效果
Jan 08 #jQuery
JS实现网站吸顶条
Jan 08 #Javascript
js实现移动端吸顶效果
Jan 08 #Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
Jan 08 #Javascript
You might like
收音机频率指针指示不准确和灵敏度低问题
2021/03/02 无线电
免费的ip数据库淘宝IP地址库简介和PHP调用实例
2014/04/08 PHP
php生成excel列名超过26列大于Z时的解决方法
2014/12/29 PHP
PHP CURL 多线程操作代码实例
2015/05/13 PHP
修复ShopNC使用QQ 互联时提示100010 错误
2015/11/08 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
2016/03/29 PHP
基于thinkPHP3.2实现微信接入及查询token值的方法
2017/04/18 PHP
js 获取中文拼音,Select自动匹配字母获取值的代码
2009/09/23 Javascript
jquery 最简单易用的表单验证插件
2010/02/27 Javascript
Jquery 获得服务器控件值的方法小结
2010/05/11 Javascript
js Function类型
2011/12/04 Javascript
JSONP 跨域共享信息
2012/08/16 Javascript
JS常用表单验证方法总结
2014/05/22 Javascript
js实现精美的图片跟随鼠标效果实例
2015/05/16 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
教你JS中的运算符乘方、开方及变量格式转换
2016/08/09 Javascript
D3.js实现饼状图的方法详解
2016/09/21 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
2016/11/09 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
bootstrap轮播模板使用方法详解
2017/11/17 Javascript
js中的 || 与 &amp;&amp; 运算符详解
2018/05/24 Javascript
在vue中给列表中的奇数行添加class的实现方法
2018/09/05 Javascript
VUE Elemen-ui之穿梭框使用方法详解
2021/01/19 Javascript
[01:00:14]DOTA2-DPC中国联赛 正赛 Ehome vs Elephant BO3 第二场 2月28日
2021/03/11 DOTA
python爬虫_自动获取seebug的poc实例
2017/08/05 Python
Python unittest如何生成HTMLTestRunner模块
2020/09/08 Python
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
EMPHASIS艾斐诗官网:周生生旗下原创精品珠宝品牌
2020/12/17 全球购物
营销与策划个人求职信
2013/09/22 职场文书
工程力学专业毕业生求职信
2013/10/06 职场文书
自我鉴定注意事项
2014/01/19 职场文书
文明村创建实施方案
2014/03/27 职场文书
乳制品整治工作方案
2014/05/29 职场文书
家长会后的感想
2015/08/11 职场文书
2016年小学生寒假总结
2015/10/10 职场文书
Smart 2 车辆代号 HC11 全新谍照曝光
2022/04/21 数码科技