本系列博客为ES6基础语法的使用及总结,如有错误,欢迎指正。
重学ES6之出来混迟早要还的(三)主要包括for of循环startsWith()endsWith()includes()repeat()padStart()padEnd() 方法。

其他笔记:
重学ES6之出来混迟早要还的(一)
重学ES6之出来混迟早要还的(二)
重学ES6之出来混迟早要还的(四)
重学ES6之出来混迟早要还的(五)
重学ES6之出来混迟早要还的(六)
数据类型的转换/判断/比较

循环的几种方式

普通for循环

for(let i=0;i<arr.length;i++){
    //内容
}

forEach循环

1.forEach的使用

  • 格式

    arr.forEach(function (element,index,array) {
       console.log(element,index,array);
    })
  • forEach方法会自动调用传入的函数
  • 每次调用都会将当前遍历到的元素和当前遍历到的索引和当前被遍历的数组传递给这个函数

2.forEach注意点

  • forEach不能终止、不能跳过(即不能在代码块里面使用break、continue)

for in循环

1.for in循环的使用

let arr = ['god','gosh','jesus','christ'];
for(let key in arr){
   console.log(key); //取出的是索引
   console.log(arr[key]); //取出的是值
}

2.for in循环的注意点

  • console.log(key); --> 取出的是索引
    console.log(arr[key]); --> 取出的是值
  • for in循环遍历的是对象上的所有可枚举属性(包括原型上面的属性)

    Array.prototype.des = function(){
       return this[0];
    };
    let arr = ['god','gosh','jesus','christ'];
    arr.title = 'words';
    for(let key in arr){
       console.log(key); //取出的是索引
       console.log(arr[key]); //取出的是值
    }

    Snipaste_2019-10-21_17-13-27.png

  • 在企业开发中不推荐使用for in循环来遍历数组
  • 对象中的属性是无序的,for in循环就是专门用于遍历无序的东西的

for-in循环是专门用于遍历对象的, 对象的属性是无序的, 所以for-in循环就是专门用于遍历无序的东西的, 因此不推荐使用for in循环来遍历数组

for of循环

1.使用格式

Array.prototype.des = function(){
   return this[0];
};
let arr = ['god','gosh','jesus','christ'];
arr.title = 'words';
for(let key of arr){
   console.log(key); //直接遍历的是值
}

2.注意点

  • console.log(key); --> 直接遍历的是值
  • 不会遍历原型上面的属性
  • 支持循环的终止和跳过

Object.keys() 方法遍历属性名

返回的是由属性名组成的数组
1.用法

  • Object.keys()将一个对象中的属性名放到一个数组中;数组中每个元素类型为string
  • 数组中属性名的排列顺序和使用for...in 循环遍历该对象时返回的顺序一致。
  • 如果对象的键-值都不可枚举,那么将返回由键组成的数组。

遍历对象时:

let object1 = {
    a: 'somestring',
    b: 42,
    c: false
};

console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]

遍历数组时(将原数组的索引放到一个数组中):

// simple array
let arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
console.log(typeof Object.keys(arr)[0]); //string

遍历类数组:

// array like object
let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

遍历对象时是无序的 (也就是上文所说的数组中属性名的排列顺序和使用for...in 循环遍历该对象时返回的顺序一致。)

// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

2.Object.keys() 方法可以用来判断一个对象是否为空
利用Object.keys() 方法返回的数组,判断该数组长度是否为0;长度为0 则代表该对象为空;反之则不为空

let object1 = {
    a: 'somestring',
    b: 42,
    c: false
};
let keys = Object.keys(object1);
console.log(keys);
console.log(keys.length === 0); //false

Object.entries() 方法遍历

返回的是键值对数组
返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。
这个方法是搜Array.prototype.entries()发现的,我没用过,只是刚好发现也可以遍历东西,所以顺便写上来了,注意与下文的数组的entries()对比
1.用法

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]


遍历类数组:

// array like object
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

遍历对象时是无序的:

// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

其他玩法:

// non-object argument will be coerced to an object
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

for of循环的再探讨

1.for of循环可以用来遍历可迭代对象,在上一篇ES6语法文章中也提到了什么是可迭代对象

可迭代对象就是部署了Iterator接口,或者是定义了[Symbol.iterator]方法的数据结构,在ES6中Iterator接口主要供for of消费。

好,弟中弟中弟又要问了:什么是[Symbol.iterator]顺手放个参考链接

a zero arguments function that returns an object,conforming to the iterator protocol
  • 只要一个数据已经实现了Iterator接口, 那么这个数据就有一个叫做[Symbol.iterator]的属性
  • [Symbol.iterator]的属性会返回一个函数
  • [Symbol.iterator]返回的函数执行之后会返回一个新对象Array Iterator {},该对象中又一个名称叫做next的方法(下文会说到)

    let arr = ['god','gosh','jesus','christ'];
    let res = arr[Symbol.iterator];
    console.log(res); //ƒ values() { [native code] }
    
    let res2 = arr[Symbol.iterator]();
    console.log(res2); //Array Iterator {}

2.Array.prototype.entries()方法

  • entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
  • arr.entries();arr[Symbol.iterator]();返回的都是新的Array Iterator对象,二者等价
let arr = ['god','gosh','jesus','christ'];
let res3 = arr.entries();
console.log(res3); //Array Iterator {}
for(let key of arr){
   console.log(key);
}

在控制台输入arr.entries(),得到这个新的Array Iterator对象

3.Array Iterator是对象,这个新的 Array 迭代器对象,它的原型(__proto__:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。

  • next方法每次执行都会返回一个对象{value: Array(2), done: false}
  • 这个对象中存储了当前取出的数据和是否取完了的标记,未取完标记是false,取完了标记是true

4.png
4.使用for of遍历arr.entries()(也就是它的iterator),返回的是一个数组,可以同时获取到原数组中每个索引的键/值对。

let arr = ['god','gosh','jesus','christ'];
for(let key of arr.entries()){
   console.log(key);
}


5.当然了,分开写分开获取也是可以的

let arr = ['god','gosh','jesus','christ'];
for(let key of arr.entries()){
   // console.log(key);
   console.log(key[0]); //获取索引
   console.log(key[1]); //获取属性值
}

可以利用解构赋值处理键值对完成后续操作

let arr = ['god','gosh','jesus','christ'];
for(let [index,value] of arr.entries()){
   // console.log(key);
   // console.log(key[0]); //获取索引
   // console.log(key[1]); //获取属性值
   console.log((`第${index + 1}个单词是${value}`));
}

6.for of循环可以用于Array/Map/Set/String/TypedArray/arguments 对象/NodeList对象。因此在遍历时不需要考虑是否可以使用哪种循环,for of可以解决这些场景;但是for of循环不支持对象的遍历

function sum() {
    let count = 0;
    for (let key of arguments){
        count = count + key;
    }
    return count;
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8));

ES6新增的字符串函数

startsWith()

(要加s,英语老师口气)
startsWith() 方法用来判断当前字符串是否以另外一个给定的子字符串开头,并根据判断结果返回 true 或 false。
1.用法 str.startsWith(searchString[, position])

  • searchString 要搜索的子字符串。
  • position 可选 在 str 中搜索 searchString 的开始位置,默认值为 0,也就是真正的字符串开头处。
  • 大小写敏感
let str = 'significant';
console.log(str.startsWith('i', 4)); //从第四个位置开始判断,返回true
console.log(str.startsWith('I', 4)); //区分大小写,返回false

endsWith()

(要加s,英语老师口气)
endsWith()方法用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回 true 或 false。
1.用法 str.endsWith(searchString[, length])

  • searchString 要搜索的子字符串。
  • length 可选。作为str的长度。默认值为str.length
  • 大小写敏感
let str = 'there are hunters';
console.log(str.endsWith('are', 9)); //相当于截取前九个字符,判断是否以are结尾

includes()

(要加s,英语老师口气)
includes() 方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。
1.用法 str.includes(searchString[, position])

  • searchString 要在此字符串中搜索的字符串。
  • position 可选。从当前字符串的哪个索引位置开始搜寻子字符串,默认值为0。
  • 可以用来替代过去的indexOf()
let str = 'there are hunters';
console.log(str.indexOf('are') !== -1); //true
console.log(str.includes('are')); //true
console.log(str.includes('are',10)); //false
console.log(str.includes('hunters',10)); //true

repeat()

别名:人类的本质是复读机之repeat方法
repeat() 构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。
1.用法

  • count 介于0和正无穷大之间的整数 : [0, +∞) 。表示在新构造的字符串中重复了多少遍原字符串。
  • 返回值是包含指定字符串的指定数量副本的新字符串。
/** 
 * str: String
 * count: Number
 */

let resultString = str.repeat(count);

2.注意点

  • 重复次数不能为负数。
  • 重复次数必须小于 infinity,且长度不会大于最长的字符串。

3.示例

"abc".repeat(-1)     // RangeError: repeat count must be positive and less than inifinity
"abc".repeat(0)      // ""
"abc".repeat(1)      // "abc"
"abc".repeat(2)      // "abcabc"
"abc".repeat(3.5)    // "abcabcabc" 参数count将会被自动转换成整数.
"abc".repeat(1/0)    // RangeError: repeat count must be positive and less than inifinity

({toString : () => "abc", repeat : String.prototype.repeat}).repeat(2)   
//"abcabc",repeat是一个通用方法,也就是它的调用者可以不是一个字符串对象.

4.现场教学
比如你在网上看到一个巨好笑的沙雕段子,此时你就可以使用这个方法打印许多的“哈哈哈”

let str = "哈".repeat(10000);
console.log(str);

padStart()

padStart()方法用另一个字符串填充当前字符串(重复,如果需要的话),以便产生的字符串达到给定的长度。填充从当前字符串的开始(左侧)应用的。

1.用法
语法:str.padStart(targetLength [, padString])

参数:①targetLength 当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
padString 可选
填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。

2.示例

注意:

  • 如果第一个参数小于当前字符串的长度,则不填充,返回当前字符串本身。
  • 如果第二个参数不传,默认用空格填充
  • 如果第二个参数使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。
'abc'.padStart(1);          // "abc"
'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0");     // "00000abc"

3.应用场景

在处理时间的时候,通常月、日、时、分、秒如果是一位数,需要在左侧添加一个0

先将得到的时间转为字符串,再使用padStart()方法判断是否需要在左侧添加0

let date = new Date(value);
let year = date.getFullYear();
let month = date.getMonth()+1+'';
let day = date.getDate()+'';
let hour = date.getHours()+'';
let minute = date.getMinutes()+'';
let second = date.getSeconds()+'';
return `${year}-${month.padStart(2,'0')}-${day.padStart(2,'0')} ${hour.padStart(2,'0')}:${minute.padStart(2,'0')}:${second.padStart(2,'0')}`;

padEnd()

padEnd() 方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。

1.用法和padStart()差不多,只不过是从当前字符串的末尾(右侧)开始填充。

2.注意点

  • 如果第一个参数小于当前字符串的长度,则不填充,返回当前字符串本身。
  • 如果第二个参数不传,默认用空格填充
  • 如果第二个参数使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。

小结: 其实我觉得这俩玩意算是在某些方面,三目运算符的简化。如果字符串本来长度大于第一个参数,则不填充;如果需要填充,按照规则适当截取即可。


本文章参考到的链接:
https://developer.mozilla.org/en-US/#


acoderbeauty
44 声望5 粉丝

菜是原罪(哭)