【js】Object上的一些方法

Object上的一些方法

  1. assign
  2. create
  3. defineProperties
  4. defineProperty
  5. keys
  6. values
  7. entries
  8. freeze
  9. isFrozen
  10. seal
  11. isSealed
  12. getPrototypeOf
  13. setPrototypeOf
  14. is
  15. isExtensible
  16. preventExtensions
  17. getOwnPropertyDescriptor
  18. getOwnPropertyDescriptors
  19. getOwnPropertySymbols
  20. getOwnPropertyNames
1.Object.assign(target,source) 将可枚举属性的值从一个或对个对象分配到目标对象,返回目标对象
const target = { a: 1, b: 2 } const source = { b: { b1: 3 }, c: 4 } const result = Object.assign(target, source) console.log(result, target); target.b.b1 = 10

【js】Object上的一些方法
文章图片

  • 可以看出assign是一种浅拷贝,没有开辟新的存储空间去存拷贝来的值,直接的引用
2.Object.create(proto,propertiesObject)
  1. 创建一个空对象
  2. 第一个参数作为该对象的原型
  3. 第二个参数为该对象的默认属性
    function School(name) { this.name = name } let obj = Object.create(School.prototype, { p: { value: 4, enumerable: false, writable: false, configurable: false }, length: { value: 0 } }) obj.q = 5 obj.p = 5 //writable为false,不可修改 delete obj.p //configurable为false,删除失败 for (let i in obj) { console.log(i); //enumerable为false,p不被枚举 } console.log(obj);

    【js】Object上的一些方法
    文章图片

    • 默认的属性可以配置属性,枚举,可写,可配置
3.Object.defindeProperty(obj,prop,descriptor)与Object.defineProperties(obj,props)
  1. Object.defindeProperty在一个对象上定义或修改一个属性,返回该对象
    • descriptor
      • writable 可写
      • enumerable 可枚举
      • configurable 可删除
      • value 值
      • get 读值
      • set 设置值
    let o = { a: { name: "张三", age: 18, } } var val = null Object.defineProperty(o.a, "rank", { configurable: false, enumerable: true, get() { console.log("获取张三排名"); return val }, set(newval) { console.log("新值:" + newval); val = newval } }) o.a.rank = 1 console.log(o.a.rank); console.log(o);

    【js】Object上的一些方法
    文章图片

    • get setvalue writable不能同时使用
    • 在添加rank值时set会监听到,可以赋值给一个中间变量或者该对象上的一个属性,get会在rank时执行
    • 点击rank的三个点也会监听到读的操作
    【js】Object上的一些方法
    文章图片

  2. Object.defineProperties(obj,props)
    defineProperty有三个参数,但是只针对一个属性
    defineProperties的第二个参数不是一个字符串,是一个对象
    它将defineProperty的第三个参数融合到第二个参数里
    可以去配置多个属性
    let o = { a: { name: "张三", age: 18, } } var val = null let a = Object.defineProperties(o.a, { "rank": { value: 1, }, "grade": { get() { console.log("读:" + val); return val }, set(newval) { console.log("改" + newval); val = newval } } } ) o.a.grade = 9 console.log(o.a.rank, o.a.grade); console.log(a);

    【js】Object上的一些方法
    文章图片

    • 属性的相关配置默认均为false
4.Object.getOwnPropertyDescriptor(obj,prop)和Object.getOwnPropertyDescriptors(obj)
  • 获取指定对象自身属性的描述符
  • 一个是获取单个,一个获取全部
    const o = {} let val = 0 Object.defineProperties(o, { a: { value: 1, enumerable: true, configurable: false, }, b: { configurable: false, enumerable: false, get() { return val }, set(newval) { val = newval } } }) let d1 = Object.getOwnPropertyDescriptor(o, "a") let d2 = Object.getOwnPropertyDescriptors(o) console.log(d1, d2);

    【js】Object上的一些方法
    文章图片

    普通的 追加对象属性,也会返回相关描述
    不过与defineProperty的默认值false正好 相反
5.Object.keys(obj) Object.values(obj) Object.entries(obj)
  • keys:返回给定对象可枚举属性值组成的数组
  • values:返回给定对象可枚举属性名组成的数组
  • entries:返回给定对象可枚举键值对组成的数组
    const o = { a: 1, b: 2, fn() { } } for (const k of Object.keys(o)) { console.log(k); //a b fn } for (const v of Object.values(o)) { console.log(v); //1 2 fu(){} } for (const e of Object.entries(o)) { console.log(e); //["a",1] ["b",2] ["fn",fn()] }

    数组原型上的keys()方法 返回的是 Number类型,Object上返回的是 字符串
6.freeze(obj) isFrozen()、seal(obj) isSealed()、preventExtensions() isExtensible
  • freeze冻结一个对象,不可修改,不可加属性,不可删属性,其原型也不能修改
  • seal封闭一个对象,可修改已有属性,不可加属性,不可删除属性,原型不可修改
  • preventExtensions不可扩展, 可删除,可修改,不可加属性,原型不可修改
    const o1 = { a: 1, b: 2, fn() { } } Object.freeze(o1) console.log(Object.isFrozen(o1)); //true o1.a = 2 console.log(o1.a); // 1const o2 = { a: 1, b: 2, fn() { } } Object.seal(o2) console.log(Object.isSealed(o2)); //true o2.a = 2 console.log(o2.a); //2const o3 = { a: 1, b: 2, fn() { } } Object.preventExtensions(o3) console.log(Object.isExtensible(o3)); //false o3.a = 2 console.log(delete o3.b); //true console.log(o3.a); //2

    freeze与seal都 不可扩展且不可删除,isExtensible的值也为 false
7.Object.setPrototypeOf(obj,prototype) Object.getPrototypeOf(obj)
  • 设置对象的原型与获取对象的原型
    const obj = { name: "obj", getName() { console.log(this.name) } } let o = { name: "o" } Object.setPrototypeOf(o, obj) Object.getPrototypeOf(o).getName()//obj o.getName()//o

    不建议使用这种方式以及__proto__去修改原型
    使用 Object.create()来创建一个指定原型的新对象
8.Object.is(value1,value2)
  • 判断两个值是否为同一个值
const o1 = { a: 1 } const o2 = { b: { c: 2 } } const o3 = { b: { c: 2 } } Object.assign(o1, o2) console.log(Object.is(o1.b, o2.b)); //true console.log(Object.is(o1.b, o3.b)); //false

引用的地址不同会检测出是不同的值
对于原始类型,只要值相同即可
可以看出Object.assign()是 浅拷贝,对用引用类型并没有开辟新的内存空间去存储,只是复制了栈指针的指向
9.Object.getOwnPropertyNames(obj)和Object.getOwnPropertySymbols(obj)
  • getOWnPropertyNames返回指定对象的属性名组成的数组,包括不可枚举的属性,但不包括Symbol值的属性名
  • getOwnPropertySymbols返回指定对象所有以Symbol为属性名的数组
    let f = Symbol("foo") const o = { [f]: 1, "a": 2, b: 3 } const n = Object.getOwnPropertyNames(o) const s = Object.getOwnPropertySymbols(o) console.log(n, s); //["a","b"] [Symbol(foo)]

原型上的方法 1.hasOwnProperty
2.isPrototypeOf
3.propertyIsEnumerable
4.toLocalString
5.toString
6.ValueOf
7.__defineGetter__(已废弃)
8.__defineSetter__(已废弃)
9.__lookupSetter__(已废弃)
10.__lookupSetter__(已废弃)
11.__proto__(属性 已废弃)
12.toSource()(非标准)
1.Object.prototype.hasOwnProperty(prop)
  • 检测指定属性是否有某个属性,可以检测到Symbol类型
    const a = [1] console.log(a.hasOwnProperty(0)); //true let s = Symbol("foo") const o = { [s]: "a", } console.log(o.hasOwnProperty(s)); //true

2.Object.prototype.isPrototypeOf(obj)
  • 检测一个对象是否在另一个对象的原型链
    function School(name) { this.name = name } School.prototype = { constructor: School, getName() { console.log(this.name); } } function Student(name) { School.call(this, name) } Student.prototype = Object.create(School.prototype) Student.prototype.constructor = Student const std1 = new Student("张三") std1.getName() //张三 console.log(School.prototype.isPrototypeOf(std1)); //true

    上面用 组合寄生的方式实现的继承
    可以检测出 父类的原型子类实例的原型链上
3.Object.prototype.peopertyIsEnumerable(prop)
  • 检测指定对象的某属性是否可枚举
    let s1 = Symbol("s1") let s2 = Symbol("s2") const o = { [s1]: 0, } Object.defineProperties(o, { [s2]: { value: 1, enumerable: true }, p: { value: 3, } }) console.log(o.propertyIsEnumerable(s1)); //true console.log(o.propertyIsEnumerable(s2)); //true console.log(o.propertyIsEnumerable("p")); //false

4.toLocalString() toString() valueOf()
  • toLocalString返回的是本地环境字符串,适合处理时间类型
  • toString返回唯一字符串,不会因为环境的改变而变化
  • valueOf返回对象的原始值
统一方法
function transform(o) { console.log(Object.prototype.toLocaleString.call(o)); console.log(Object.prototype.toString.call(o)); console.log(Object.prototype.valueOf.call(o)); }

基本数据类型
transform(1000) //"1000" "[object Number]" {1000} transform(true) //"true" "[object Boolean]" {true} transform(Symbol("smb")) //"Symbol('smb')" "[object Symbol]" {Symbol(smb)} transform(1000n) //"1000" "[object BigInt]" {1000n} transform("str") //"str" "[object String]" {"str"}

【【js】Object上的一些方法】引用数据类型
transform([0, 1]) //"0,1" "[object Array]" [0,1] transform({ a: 0, b: 1 }) //"[object Object]" "[object Object]" {a:0,b:1} transform(new Date()) //"标准时间" "[object Date]" "标准时间" transform(function () { }) //"function () { }" "[object Function]" f () {} transform(new Error("e")) // "Error:e" "[object Error]" Error: e

  • 可以看出toLocalString返回其内容的字符串
  • toString返回值唯一 都是方括号object + 数据类型的字符串
  • valueOf基本类型会返回一个对象 引用类型返回其本身

    推荐阅读