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 是一个空的对象常量,即它没有属性。