彻底弄懂 Object 上的静态方法

本文详细解读了JavaScript中的静态方法,如Object.defineProperty()、Object.assign()、Object.is()等,以及原型对象上的关键方法,如toString.call()。讲解了它们的用途、实现原理和注意事项,对于理解JS对象的本质和源码至关重要。

静态方法:是一种只能通过函数名访问的方法,我们都知道,Object是所有类型的起源,无论是 Function 还是Array,最终都会回归到Object的身上。

console.log(Function instanceof Object) // true
console.log(Array instanceof Object) // true

因此掌握 Object 的静态方法和原型对象上(prototype) 的方法是至关重要的,虽然我们在编程中可能不会经常用到,但是它对于我们深入理解 js,和学习源码上有着不可分割的作用。

一. 静态方法

1. Object.defineProperty()

说到对象,最重要的就是该方法,它也是 vue2 实现响应式原理最重要的思想。首先来看下它的属性值,分为数据属性和访问器属性。

  • 数据属性
    configurable: 表示是否可以通过delete删除并重新定义属性,是否可以修改他的特性,切记该值一旦改为false, 则无法改回
    Enumberable: 表示属性是否可以通过枚举获取,也就是不可使用 for-in, Object.keys() 等方法获取。
    Writable: 表示属性值是否为可修改的。
    Value: 表示属性的实际值。
  • 访问器属性
    Get: 获取函数,在读取该属性时触发。
    Set: 设置函数,在写入属性时触发。

了解了这些属性之后,你也就了解了创建一个对象真正的过程,但是我们再不使用这些高级功能时,创建对象的方式还是使用 let obj = {} 更加方便,而使用该方法创建对象时,上边对应的属性默认值都是true,但是我们在使用该方法给对象定义键值时,则上述属性默认为false
与之相关联的方法

  • Object.defineProperties(): 用来给对象同时定义多个键值
  • Object.getOwnPropertyDescriptor: 用来获取该对象键值的属性描述符,也就是使用 Object.defineProperty为对象键值设置的属性.
2. Object.assign

该方法接受一个目标对象和一个或多个源对象作为参数,然后将每个源对象中可枚举属性复制到目标对象,也就是说 Enumberable值为 false 的值不会被合并到源对象中。

       let obj3 = {
           name: '石头山'
       }
       Object.defineProperty(obj3, 'age',{
           value: '18',
           enumerable: false
       })
       let obj4 = {}
       Object.assign(obj4, obj3)
       console.log(obj4) // 只有 name属性, 而没有 age 属性

了解了它的作用后,我们还需要了解它的实现原理,才能使用起来更加得心应手。
其实该方法的思想,就是使用源对象上的Get方法,取得属性的值,然后使用目标对象上的Set 设置属性的值。
注意点:

  1. 当多个源对象中含有相同的键值时,设置的为最后一个源对象中的值
  2. 该方法其实是浅复制,只是简单的将源对象中的值复制了过来
        let obj = {};
        let obj1 = {
            name: {
                first: '石'
            }
        }
        Object.assign(obj, obj1);
        console.log(obj.name === obj1.name)
  1. 我们可以通过改写SetGet来修改该函数的默认行为
    可以看到,本应该得到的是石头山,由于我们修改了源对象的Get属性,修改了其默认行为,得到的便是我们返回的哈哈哈
       let obj = {}
       let obj1 = {
           name: '石头山',
           get name(){
            return '哈哈哈'
           }
       }
       Object.assign(obj, obj1)
       console.log(obj) // { name: '哈哈哈' }
3. Object.is

该方法的出现,弥补了 ===的不足,该方法接收两个参数,返回一个布尔值

console.log(+0 === -0) // true
console.log(+0 === 0) // true
console.log(-0 === 0) // true
console.log(NaN === NaN) // false
// 使用Object.is 方法
console.log(Object.is(+0, -0)) // false
console.log(Object.is(+0, 0)) // true
console.log(Object.is(-0, 0)) // false
console.log(Object.is(NaN, NaN)) // false
4. Object.create

作用:该方法用来创建一个对象,并且指定该对象的[[prototype]]属性。该方法的出现来防止直接通过__proto__修改对象的[[prototype]]属性造成的性能损耗而出现的。

     let obj = {
         name:'石头山'
     }
     let obj2 = Object.create(obj)
     console.log(obj2.__proto__ === obj) // true
     console.log(Object.getPrototypeOf(obj2)) // {name: '石头山'}

与之相关联的方法

  • Object.getPrototypeOf: 用来获取当前对象的原型指向
  • Object.setPrototypeOf: 用来设置当前对象的原型指向
5. Object.keys、Object.values、Object.entries

对象迭代:三个方法都是接收一个对象参数,返回该对象的键值,值和键值对数组

二. 原型对象上的方法

1. Object.prototype.toString.call()

该方法可以有效的判断当前数据的数据类型

     console.log(Object.prototype.toString.call(arr)) // [object Array]
     console.log(Object.prototype.toString.call(obj)) // [object Object]
     console.log(Object.prototype.toString.call(str)) // [object String]
     console.log(Object.prototype.toString.call(boolean)) // [object Boolean]
     console.log(Object.prototype.toString.call(symbol)) // [object Symbol]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员-石头山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值