每天10个前端小知识(4day)

一、string 类型是可迭代的。

来看下面的例子

[...'Lydia']//["L", "y", "d", "i", "a"]

string 类型是可迭代的。扩展运算符将迭代的每个字符映射成一个元素。

二、map函数没有返回值时

来看下面的例子

[1, 2, 3].map(num => {
  if (typeof num === "number") return;
  return num * 2;
});

这是会返回[undefined, undefined, undefined],这是因为对数组进行映射的时候,num就是当前循环到的元素. 在这个例子中,所有的映射都是number类型,所以if中的判断typeof num === "number"结果都是true.map函数创建了新数组并且将函数的返回值插入数组。 但是,没有任何值返回。当函数没有返回任何值时,即默认返回undefined.对数组中的每一个元素来说,函数块都得到了这个返回值,所以结果中每一个元素都是undefined.

三、delete操作符

看下面的例子

const name = "Lydia";
age = 21;

console.log(delete name);
console.log(delete age);

这时候会输出false, true,这是因为delete操作符返回一个布尔值: true指删除成功,否则返回false. 但是通过 varconst 或 let 关键字声明的变量无法用 delete 操作符来删除。 name变量由const关键字声明,所以删除不成功:返回 false. 而我们设定age等于21时,我们实际上添加了一个名为age的属性给全局对象。对象中的属性是可以删除的,全局对象也是如此,所以delete age返回true.

四、defineProperty方法

来看下面的例子

const person = { name: "Lydia" };

Object.defineProperty(person, "age", { value: 21 });

console.log(person);
console.log(Object.keys(person));

我们发现输出的是{ name: "Lydia", age: 21 }, ["name"]

通过defineProperty方法,我们可以给对象添加一个新属性,或者修改已经存在的属性。而我们使用defineProperty方法给对象添加了一个属性之后,属性默认为 不可枚举(not enumerable)Object.keys方法仅返回对象中 可枚举(enumerable) 的属性,因此只剩下了"name". 用defineProperty方法添加的属性默认不可变。你可以通过writableconfigurable 和 enumerable属性来改变这一行为。这样的话, 相比于自己添加的属性,defineProperty方法添加的属性有了更多的控制权。

五、JSON.stringify的第二个参数

还是先来看下面的例子

const settings = {
  username: "lydiahallie",
  level: 19,
  health: 90
};

const data = JSON.stringify(settings, ["level", "health"]);
console.log(data);

发现输入的是"{"level":19, "health":90}"

JSON.stringify的第二个参数是 替代者(replacer). 替代者(replacer)可以是个函数或数组,用以控制哪些值如何被转换为字符串。 如果替代者(replacer)是个 数组 ,那么就只有包含在数组中的属性将会被转化为字符串。在本例中,只有名为"level" 和 "health" 的属性被包括进来, "username"则被排除在外。 data 就等于 "{"level":19, "health":90}". 而如果替代者(replacer)是个 函数,这个函数将被对象的每个属性都调用一遍。 函数返回的值会成为这个属性的值,最终体现在转化后的JSON字符串中(译者注:Chrome下,经过实验,如果所有属性均返回同一个值的时候有异常,会直接将返回值作为结果输出而不会输出JSON字符串),而如果返回值为undefined,则该属性会被排除在外。

六、reduce函数没有返回值的时候

还是来看下面的例子

[1, 2, 3, 4].reduce((x, y) => console.log(x, y));

此时输入的是1 2 and undefined 3 and undefined 4

reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组) reducer 函数的返回值将会分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。 reducer 函数还有一个可选参数initialValue, 该参数将作为第一次调用回调函数时的第一个参数的值。如果没有提供initialValue,则将使用数组中的第一个元素。 在上述例子,reduce方法接收的第一个参数(Accumulator)是x, 第二个参数(Current Value)是y。 在第一次调用时,累加器x1,当前值“y”2,打印出累加器和当前值:12。 例子中我们的回调函数没有返回任何值,只是打印累加器的值和当前值。如果函数没有返回值,则默认返回undefined。 在下一次调用时,累加器为undefined,当前值为“3”, 因此undefined3被打印出。 在第四次调用时,回调函数依然没有返回值。 累加器再次为 undefined ,当前值为“4”。 undefined4被打印出。

七、构造函数中的super关键字

先来看下面的例子,使用哪个构造函数可以成功继承 Dog 类?

class Dog {
  constructor(name) {
    this.name = name;
  }
};

class Labrador extends Dog {
  // 1 
  constructor(name, size) {
    this.size = size;
  }
  // 2
  constructor(name, size) {
    super(name);
    this.size = size;
  }
  // 3
  constructor(size) {
    super(name);
    this.size = size;
  }
  // 4 
  constructor(name, size) {
    this.name = name;
    this.size = size;
  }

};

运行这个函数,发现只有2是满足条件的,这是因为在子类中,在调用super之前不能访问到this关键字。 如果这样做,它将抛出一个ReferenceError:1和4将引发一个引用错误。 使用super关键字,需要用给定的参数来调用父类的构造函数。 父类的构造函数接收name参数,因此我们需要将name传递给super。 Labrador类接收两个参数,name参数是由于它继承了Dogsize作为Labrador类的额外属性,它们都需要传递给Labrador的构造函数,因此使用构造函数2正确完成。

八、import的在js中的执行顺序

来看下面的例子

// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1, 2));

// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;

此时,输出的结果是running sum.js, running index.js, 3

这是因为import命令是编译阶段执行的,在代码运行之前。因此这意味着被导入的模块会先运行,而导入模块的文件会后执行。 这是CommonJS中require()import之间的区别。使用require(),您可以在运行代码时根据需要加载依赖项。 如果我们使用require而不是importrunning index.jsrunning sum.js3会被依次打印。

九、padStart方法

还是通过用下面的例子来理解

const name = "Lydia Hallie"
console.log(name.padStart(13))
console.log(name.padStart(2))

这是输出的是" Lydia Hallie", "Lydia Hallie" ("[1x whitespace]Lydia Hallie", "Lydia Hallie")

这是因为使用padStart方法,我们可以在字符串的开头添加填充。传递给此方法的参数是字符串的总长度(包含填充)。字符串Lydia Hallie的长度为12, 因此name.padStart(13)在字符串的开头只会插入1(13 - 12 = 1)个空格。 如果传递给padStart方法的参数小于字符串的长度,则不会添加填充。

十、String.raw函数

还是通过一个例子来理解

console.log(String.raw`Hello\nworld`);

此时输出的是Hello\nworld

String.raw函数是用来获取一个模板字符串的原始字符串的,它返回一个字符串,其中忽略了转义符(\n\v\t等)。但反斜杠可能造成问题,因为你可能会遇到下面这种类似情况:

const path = `C:\Documents\Projects\table.html`
String.raw`${path}`

这将导致: "C:DocumentsProjects able.html" 直接使用String.raw

String.raw`C:\Documents\Projects\table.html`

它会忽略转义字符并打印:C:\Documents\Projects\table.html 上述情况,字符串是Hello\nworld被打印出。

以上所有内容,均参考

首页 - 前端面试题宝典 (ecool.fun)icon-default.png?t=M7J4https://fe.ecool.fun/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值