Object

_.isEqual()

1 .判断两个值是否相等
2 .深度进行判断

_.isMatch()

1 .深度搜索是否有某个值

_.isOlainObject(value)

1 .检查value是否是普通对象,也就是该对象由Object 构造函数创建,或者[[Prototype]]为空
2 .

_.toPlainObject()

1 .转换为普通对象,甚至对象继承的可枚举属性也一并继承
2 .

assign()

1 .对象合并,但是原生的方法是只会进行浅复制,如果源对象的某个属性的值是对象,那么目标拷贝的是这个对象的引用。
2 .只拷贝源对象自身的属性,不拷贝继承属性,也不拷贝不可枚举的属性

let b1={
    'name':123
}

let o1={
    'name':b1
}

let o2={
    'age':20
}
cc(o1)
b1.name='asdfasd'
cc(Object.assign(o1,o2))

1 .可以发现,当修改b1的时候,后面合并的的数组还是会发生变化,那这样就很麻烦了。要不就是保证后面的数组在合并之后被冻结,不然永远不能保证这个数据是固定的
2 .自己写一个合并的函数,是深度遍历合并的
3 .在合并之前,合并的是克隆之后的函数,这样原来怎么改都不会影响到现在的数组了。

let b1={
    'name':123
}

let o1={
    'name':b1
}

let o2={
    'age':20
}
cc(o1)
let xx=Object.assign(o2,_.cloneDeep(o1))
cc(xx)
b1.name='asdfasd'
cc(o1)
cc(xx)

3 .拷贝继承链 _.assignIn:类似于assign,但是会遍历并继承来源对象的属性

function clone(origin){
    let originProto=Object.getPrototypeOf(origin)
    return Object.assign({},originProto, origin);
}

function assign(obj,arr){
    let re=Object.assign({},obj)
    for (let i of arr){
        Object.assign(re,clone(i))
    }
    cc(re)
    return re
}

assign({},[new f11,new foo])

4 ..assignWith():拷贝选项参数,在遍历的时候先检查属性值,如果属性值不符合给定的约定函数,那么不进行合并
5 .
.at(object, [paths])

1 .如果是选object里面的数据的话,数组的参数是要要选的数据的路径
var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

c(_.at(object,['a[0].b.c'],'a[1]'))

let arr=['a','f','c']

c(_.at(arr,2))
2 .如果选的arr里面的数据的话,参数是数组内的索引

create() :创建一个继承对象的对象

1 .这个直接使用es6语法实现,非常简单
2 .这个不能写成调用函数,应该始终使用语法来实现,因为super的时候需要继承上个对象的属性,这个如果把要继承的对象按照一个函数的参数传进去的话,是无法得到这个东西的
3 .子类必须在sonstructor中调用super方法。子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后对其进行加工,加上子类自己的实例属性和方法,如果不调用super方法,子类就得不到this对象
4 .ES5继承方式:先创建子类的实例对象this,然后将父类的方法添加到this上面
5 .ES6继承机制:先将父类实例对象的属性和方法,添加到this上面,然后在根据子类的构造函数修改this.

1 .所以可以继承原生构造函数定义子类,可以继承父类的所有行为
2 .es6可以自定义原生的数据结构(Array,String)的子类
3 .extends关键字不仅可以继承类,还可以继承原生的构造函数

6 .super

1 .super最为函数调用,代表父类的构造函数,用在子类继承的时候。
class Shape{
    constructor(x,y){
        this.x=x
        this.y=y
    }
    p(){
        return '2'
    }
    p2(){
        return this.x
    }

}
class Circle extends Shape{
    constructor(x,y,color){
        super(x,y)
        // 调用父类的constructor(x,y),
        // super虽然代表的是父类的构造函数,但是返回的是子类的实例,super内部的this指的是当前的子类
        this.color=color;

        // console.log(super.x)
        // 指向父类的原型对象,所以定义在父类实例上的方法或者属性是无法通过super调用的--返回undefined

        // console.log(super.p2())
        // 可以通过这样的拐弯来实现可以访问。其实访问的是Shape.prototype.p()
        // 也就是说上面的x属性如果这样定义的话,是可以获取到的
    }
    tostring(){
        console.log(super.p2())
        // 在子类普通方法内使用super,内部的this指向当前的子类实例
    }
}
const c1=new Circle(10,10,'red')
2 .super作为对象时,在普通方法中,指向父类的原型对象,在静态方法中,指向父类
3 .由于this指向子类实例,如果不用this,而是使用super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性
4 .

7 .类的prototype属性与proto属性(表示继承,或者说谁给了他这个属性)

1 .子类的__proto__属性,表示构造函数的继承,总是指向父类
2 .子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性
3 .
class b extends Object{}
// 子类继承Object类
cc(b.__proto__==Object)
cc(b.prototype.__proto__==Object.prototype)

class bb{}
// 子类什么都继承,就是个普通函数

cc(bb.__proto__==Function.prototype)
// 此时子类就是一个普通函数,所以直接继承自Function.prototype
cc(bb.prototype.__proto__==Object.prototype)
// bb调用之后返回一个空对象,所以指向构造函数Object的prototype属性

4 .实例的proto属性:唯一作用,可以通过子类实例来修改父类实例的行为

class a{
    constructor(x){
        this.x=x
    }
}
class aa extends a{
    constructor(x){
        super(x)
    }
}

const a1=new a('10')
const a2=new aa()
cc(a2.__proto__.__proto__==a1.__proto__)
cc(a2.__proto__)
//aa{}
cc(a2.__proto__.__proto__)
// a{}
a2.__proto__.__proto__.say=function(){
    console.log('sasasa')
}
a2.say()
a1.say()

.defaults(object, [sources]),.defaultsDeep(object, [sources])

1 .分配来源对象的可枚举属性到目标对象所有解析为 undefined 的属性上。 来源对象从左到右应用。 一旦设置了相同属性的值,后续的将被忽略掉。
2 .Object.assign()方法不能实现的东西

1 .对于object.assign来说,如果第一个参数不是对象的话,则会先转会对象
2 .对于非首参数出现非对象,如果不能转换为对象,都是会跳过的。
3 .拷贝得属性是有限制得,只能拷贝源对象的自身属性,不拷贝不可枚举的属性enumerable:false
4 .浅拷贝:如果源对象某个属性的值是对象,那么目标对象拷贝的是这个对象的引用.lodash 的defaultsDeep实现了这个操作,可以合并拷贝新的对象。
5 .同名属性的替换:嵌套的对象,遇到同名属性,是替换,而不是添加

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }

let o2=_.defaultsDeep({},target,source)
cc(o2)
//{ a: { b: 'c', d: 'e' } }
//注意在嵌套数组的合并中,也是按照外面的策略,如果原来有的话,就不再添加后面的了。
//解决的是object.assign方法整个替换a后面的情况

6 .取值函数的处理:只能进行值的复制,如果要复制的是一个取值函数,那么求值之后进行复制
7 .

findKey()

1 .按照value的属性来进行条件选择,返回整个key-vallue键值对


.forIn(object, [iteratee=.identity]):遍历对象的自身和继承的可枚举属性

1 .也是无法保证遍历的顺序

_.forOwn:遍历自身的可枚举属性

1 .也是无法保证遍历顺序

_.functions:返回一个function对象自身可枚举属性名的数组

_.functionsIn:返回一个function对象和继承的可枚举属性名的数组

_.get(object, path, [defaultValue]):根据对象路径获取值。如果解析value是undefined会以defaultValue取代

_.has(object,path):检查path是否是对象的直接属性

1 .返回对象的所有属性,然后进行数组的检查
2 .直接使用in 语法

_.invert(obj):反转对象的key和value

1 ..invertBy(obj,fn):传入两个参数,反转对象的key和value,并且在反转的时候对key进行处理
2 .
.invertByAll(obj,fn1,fn2):传入3隔参数,反转对象的key和val,并且在反转的时候同时对key,value进行处理

let obj={
    'name':'libater',
    'age':20
}
cc(_.invert(obj))
cc(_.invertBy(obj,(k)=>{
    return 'change'+k
}))

一些按照路径选择key,value的函数

1 ._.invoke(object, path, [args])
2 .

_.keys()

1 .创建object自身可枚举属性名为一个数组(非对象的值会被强制转换为对象)
2 ..keysIn()创建object自身或继承的可枚举属性名为一个数组
3 .
.mapKeys()这个方法创建一个对象,对象的值与源对象相同,但 key 是通过 iteratee 产生的。
4 ..mapValues()创建一个对象,对象的key相同,值是通过 iteratee 产生的。 iteratee 会传入3个参数: (value, key, object)
5 .
.values()
6 ._.valuesIn()

_.merge()

1 .递归合并来源对象的自身和继承的可枚举属性到目标对象,跳过来源解析为undefined的属性,数组和普通对象会递归合并,其他对象和值会被直接分配。来元对象从左到右分配,后续的来源对象属性会覆盖之前分配的属性
2 ..mergewith(object, sources, customizer):类似于merge,但是接收一个参数决定如何合并,如果customizer返回undefined将会由合并处理方法代替
3 .
.

_.omit(object, [props])

1 .返回忽略属性之外的自身和继承的可枚举属性。就是删去括号里面的属性
2 .这个方法其实很弱智啊。自己写的话很简单啊
3 ..omitBy(object, [predicate=.identity])进过predicate判断是不是真值的属性和自身和继承的可枚举属性
4 ._.

_.pick(object, [props])

1 .从一个对象选出选中属性的对象
3 .pickBy(object, [predicate=.identity]):类似上面的东西

_.result(object, path, [defaultValue])

1 .除了如果解析得到的值是一个函数的话,就绑定this到这个函数并返回执行后的结果。
2 .

_.set(object, path, value)

1 .设置值到对象对应的属性路径上,如果没有则创建这部分路径。 缺少的索引属性会创建为数组,而缺少的属性会创建为对象
2 ._.unset(obj,path):移除对象路径的属性

_.toPairs(obj)

1 .创建一个对象自身可枚举属性的键值对数组
2 ._.toPaireIn():创建一个对象自身和继承的可枚举属性的键值对数组

_.to

你可能感兴趣的:(Object)