重学es6 - 第四部分 | 8月更文挑战

243 阅读4分钟

数组方法

上一次我们在最后介绍了一些数组方法findfillmapreducefilterforEach,我们先接着上次没介绍完的数组新方法. 如果想了解上边方法的话,可以看我的上一篇文章. 下面我们介绍一些不是特别常用但是也比较有用的方法.

every

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值

比如我们之前写业务代码,可能会是这样的

// 假如写一个你画我猜的游戏,规则规定必须边画边猜才能走下一步
if (isDraw() && isTalk()) {
    // xxx
}
// 那么你也可以这样写
let flag = [isDraw, isTalk].every((func) => { return func() })
if (flag) {
    // xxx
}

以上是一种场景, 但是其实用的并不多, 因为第一种方式其实看起来更简单更直观,没事可以用来装杯就是~ 一般场景是可能有一个数组, 然后判断数组是否都满足某一个条件, 比如一下

const flag = [2,4,6,8,10].every((it) => it % 2 == 0) // true

所有数据都满足条件的情况下,就返回true 下面我们可以自己写一个every方法,进一步理解它的工作原理

Array.prototype.everyTest = function (callback) {
    for (let i = 0; i < this.length; i++) {
        // 如果回调函数返回的数据是false,则直接跳出循环
        if (!callback(this[i])) {
            return false
        }
    }
    // 如果正常走到这里的话,则证明返回的数据都是true,则返回true
    return true
}
// 测试一下
[2,4,6,8,10].everyTest((it) => it % 2 == 0) // true

some

some其实用法和every是一样的,只是意义上有一些区别. some方法的话,就是如果数组中的项有一个满足条件的话,则返回true. 可以理解every就是操作符,some就是操作符.

// 因为数组里边有一个4,取余是0. 所以返回的值还是true
[1,3,4,7,9].some((it) => it % 2 == 0) // true

下面我们也来实现一下some这个方法

Array.prototype.someTest = function (callback) {
     for (let i = 0; i < this.length; i++) {
        // 如果有返回true的话,则返回true
        if (callback(this[i])) {
            return true
        }
    }
    // 如果正常走到这里的话,则证明返回的数据都是false,则返回false
    return false
}
[1,3,4,7,9].someTest((it) => it % 2 == 0) // true

findIndex

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

一般情况我们找索引直接用[].indexOf(xx)的话就行,这个方法,我们一般用在存放对象的数组里边找索引.

[{id: 1, name: 'a'},{id: 2, name: 'b'},{id: 3, name: 'c'}].findIndex((it) => {
    return it.id == 2
}) // 1

下面我们也写一下这个方法如何实现

Array.prototype.findIndexTest = function (callback) {
     for (let i = 0; i < this.length; i++) {
        // 如果有返回true的话,则返回true
        if (callback(this[i])) {
            return i
        }
    }
    // 如果正常走到这里的话,则证明返回的数据都是false,则返回-1
    return -1
}
[{id: 1, name: 'a'},{id: 2, name: 'b'},{id: 3, name: 'c'}].findIndexTest((it) => {
    return it.id == 2
}) // 1

对象新增的方法

es6中新增的方法并不多,下面我们来列举一些

Object.is()

Object.is() 方法判断两个值是否为同一个值。如果满足以下条件则两个值相等

它可以接受两个参数.

  • 参数1: 被比较的第一个值
  • 参数2: 被比较的第二个值
  • 返回一个Boolean值, true则证明两个值相等,否则不相等
Object.is(undefined, null) // false
Object.is(undefined, false) // false
Object.is(undefined, undefined) // flase
let json1 = { name: 123 }
let json2 = { name: 123 }
let json3 = json1
Object.is(json1, json2) // false
Object.is(json1, json3) // true
NaN === NaN // false
Object.is(NaN, NaN) // true

上边的测试结果已经可以说明一些问题了, 如果是值的话, 需要值相等则为true, 如果是引用类型的话,需要是引用的同一个内存才会相等.

Object.assign()

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象

下面我们可以先看一下不同数据的测试结果

//  返回的值json和目标对象json1是相等的
let json1 = { name: 'james' }
let json2 = { age: 123 }
let json = Object.assign(json1, json2) // json1: 目标对象, json2, 源对象
json.name = 'bob'
console.log(json1.name) // bob
Object.is(json, json1) // true

针对上边的情况, 所以为了修改json, 不会修改到json1的值的话, 我们一般这么做

let json = Object.assign({}, json1, json2)

// 如果后边的源对象的值和目标对象有重合的话, 取最后一个源对象的值

let json1 = { name: 'james' }
let json2 = { age: 123 }
let json3 = { name: 'bob', sex: 'male' }
Object.assign(json1, json2, json3) // {name: "bob", age: 123, sex: "male"}

Object.setPrototype

Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null

其实这个跟之前我们写原型链用的obj.__proto__是一样的. 只是__proto__这种设置原型的方式本身就并不是浏览器推荐的一种方式. 所以es6后才引入了这种修改原型更合适的方法. 用法: Object.setPrototypeOf(obj, prototype) 下面给大家写一个比较好玩的代码

let person = { level: 1 } // {level: 1}
Object.setPrototypeOf(person, {level: 2})
person.__proto__ // {level: 2}
Object.setPrototypeOf(person.__proto__, {level: 3})
person.__proto__.__proto__ // {level: 2}
person.level // 1
delete person.level
person.level // 2
delete person.__proto__.level
person.level // 3

这涉及到一个原型链的知识,在person对象上设置原型为{level: 2}, 在person原型上再设置原型为{level: 3}, 这时候,用delete去删除掉person.level的话,再去访问person.level属性,因为personlevel已经被删除了,则会去原型上查找是否有level,然后查找到了,返回了2,再删除person原型链上的level属性,那么它又会再往上一层去查找level,找到了,然后返回了3. 这在我来看,有点像盗梦空间的感觉. 三层梦境. 我在第五层,你在大气层嘛? 哈哈哈哈.

结语

好了,今天介绍了一些es6的数组的方法,和对象的方法. 并实现了部分的es6的方法, 让大家更清楚里边的原理. 那么今天就这样咯. 下次见!