充分了解JavaScript中【对象】的概念(三)

简介: 这篇文章我们继续来讲解JavaScript中【对象】的概念,因为这是一系列的文章,所以建议从第一篇文章开始看,没看过之前文章的小伙伴,可以点击以上链接进行查看

对象的特性


对象一共有三个对象特性,他们分别是:


  1. 对象的原型: 每个对象(除了null)都与另一个对象相关联,并且继承另一个对象的属性或方法。


  1. 对象的类: 是一个标识对象类型的字符串


  1. 对象的扩展标记: 指明了是否可以向该对象添加新的属性


(1)对象的原型


在上面我已经花一定的篇幅去介绍了对象的原型了,这里就不再做过多的介绍了。这里再介绍两种判断原型的方法,第一个是 Object.getPrototypeOf(),第二个是 ifPrototypeOf()


  • Object.getPrototypeOf( )


这个方法是ES5新增的方法,它需要传入对象作为参数,然后就会返回这个对象的原型,来看一下例子


    let obj = Object.create({x:1})   //新建一个对象obj继承于 {x:1}
    Object.getPrototypeOf(obj)       //返回  {x:1}


    • isPrototypeOf( )


    该方法可以判断一个对象是否是另一个对象的原型,或者说在另一个对象的原型链上。来看一下例子


    let obj1 = {x:1}let obj2 = Object.create(obj1)
    obj1.isPrototypeOf(obj2)         //返回true,因为obj2就是继承于obj1
    Object.prototype.isPrototypeOf(obj2)  //返回true,因为Object.prototype在obj2的原型链上


    (2)对象的类


    对象也是有类型的,这个我在本文的开头也就列举了,对象一共有这三大类,分别是内置对象 、宿主对象 、自定义对象。


    我们如何来区分对象的具体类型呢?其实在 Object.prototype 中定义了一个方法属性,叫做 toString,调用该方法,并传入一个对象,就会返回一个字符串,字符串里的信息就用以表示对象的类型。


    我们直接通过 Object.prototype.toString.call(obj) 来判断对象的类型,这里用到的 call 的作用就是将 toString 方法内部的 this 指向我们要判断的对象,如果有不懂的小伙伴可以去查看一下我的另一篇介绍call的文章


      //先将 Object.prototype.toString.call() 封装成一个函数,方便后面的代码简化function classof(obj) {  return Object.prototype.toString.call(obj)}
      classof(null)                         //[object Null]classof(undefined)                    //[object Undefined]classof(1)                            //[object Number]classof("")                           //[object String]classof(true)                         //[object Boolean]classof({})                           //[object Object]classof([])                           //[object Array]classof(/\d+/)                        //[object RegExp]classof(new Date())                   //[object Date]classof(window)                       //[object window]classof(document)                     //[object HTMLDocument]function a() {}classof(new a())                      //[object Object]let b = {}classof(b)                            //[object Object]let c = Object.create(b)classof(c)                            //[object Object]


      简单总结一下


      1. 继承于内置对象的对象,会返回一个字符串,字符串里包含了该内置对象的构造函数名


      1. 判断宿主对象的类型时,例如判断window对象的类型,需要在浏览器环境下才能判断。


      1. 通过对象直接量 、调用构造函数(new fn())以及Object.create() 这三种方式创建的自定义对象,他们的对象类型都为 [object Object]


      (3)对象的扩展


      对象是具有扩展性的,其表示能否给对象添加新的属性。一般情况下,对象都是可扩展的,除非我们将他转换成了不可扩展的。接下来我们来看几个将对象转换成不可扩展的方法。


      • Object.preventExtensions( )


      我们要想将一个可扩展的对象转换成不可扩展的,我们需要调用

      Object.preventExtensions() ,将需要转换的对象作为参数传入即可。


      注意


      1. 对象一旦转换成不可扩展,就无法再转成可扩展的了


      1. 对象转换成不可扩展,只会影响该对象本身,但不会影响原型。即无法给该对象添加新的属性,但是我们可以给该对象的原型添加新的属性,该对象可以继承原型中的新属性。


      好了废话不多说,接下来看一个例子


        let obj1 = {x:1}let obj2 = Object.create(obj1)     //obj2继承于Obj1obj2.z = 4                         //给obj2添加一个属性z,值为4console.log(obj2)                  //打印  {z:4}Object.preventExtensions(obj2)     //将obj2转换成不可扩展的obj2.y = 2                         //尝试向obj2中添加新属性yconsole.log(obj2.y)                  //  打印 undefined ,说明obj2是不可扩展的
        obj1.y =  2console.log(obj2.y)          // 打印 2 ,说明obj2虽然被转换成不可扩展的了,但是还是能从原型继承属性的
        delete obj2.z                 //打印  {},说明使用Object.preventExtensions()将对象转换成不可扩展后,虽然无法添加属性,但是可以删除属性


        我们可以将对象传入 Object.isExtensible() 来判断对象是否为可扩展的。


        • Object.seal( )


        该方法是ES5中提供的,不仅具有能将对象转换成不可扩展的作用(无法添加新属性),而且还能使对象中的自有属性都设置为不可配置的,即无法删除自有属性了。我们可以成为将对象封闭


          let obj1 = {x:1}let obj2 = Object.create(obj1)     //obj2继承于Obj1obj2.z = 4                         //给obj2添加一个属性z,值为4console.log(obj2)                  //打印  {z:4}Object.seal(obj2)                  //将obj2封闭
          delete obj2.z                 //打印  {z:4},说明使用Object.seal()将对象封闭后,既无法添加属性,也无法删除属性
          obj2.z = 100                   //修改obj2中的属性z为100console.log(obj2)              //打印  {z:100} ,说明已封闭的对象,还是可以对其属性进行修改的


          我们可以将对象传入 Object.seal() 中,判断对象是否已封闭


          • Object.freeze( )


          该方法也是ES5中提供的,它在 Object.seal() 的基础之上,增加了一个限制,即将对象的自有的所有数据属性设置为只读。我们把这种限制叫做冻结


            let obj1 = {x:1}let obj2 = Object.create(obj1)     //obj2继承于Obj1obj2.z = 4                         //给obj2添加一个属性z,值为4console.log(obj2)                  //打印  {z:4}Object.freeze(obj2)                  //将obj2冻结
            obj2.z = 100                   //修改obj2中的属性z为100console.log(obj2)              //打印  {z:4} ,说明已冻结的对象,无法修改对象中的属性值

            我们可以将对象传入 Object.isFrozen() 中,判断对象是否已冻结


            结束语


            好了,洋洋洒洒这一系列文章也写完了,写加上思考理解大概耗时有十几个小时吧,说真的,刚开始写这篇文章的时候,自己对于 “对象” 这个概念也不是说很透彻很透彻,但是我为了让大家能明白,自己也花了很多的心思去研究,去理解。到现在完结,我对 “对象” 的概念也是有了更深的理解了。


            真的是原创不易啊,大家觉得写的不错的点个关注,点个赞,感谢啦~


            相关文章
            |
            21天前
            |
            JavaScript 前端开发
            如何在 JavaScript 中使用 __proto__ 实现对象的继承?
            使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
            |
            25天前
            |
            Web App开发 JavaScript 前端开发
            如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
            【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
            |
            25天前
            |
            JavaScript 前端开发 图形学
            JavaScript 中 Math 对象常用方法
            【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
            |
            2月前
            |
            设计模式 JavaScript 前端开发
            探索JavaScript中的闭包:从基础概念到实际应用
            在本文中,我们将深入探讨JavaScript中的一个重要概念——闭包。闭包是一种强大的编程工具,它允许函数记住并访问其所在作用域的变量,即使该函数在其作用域之外被调用。通过详细解析闭包的定义、创建方法以及实际应用场景,本文旨在帮助读者不仅理解闭包的理论概念,还能在实际开发中灵活运用这一技巧。
            |
            2月前
            |
            存储 JavaScript 前端开发
            JavaScript 对象的概念
            JavaScript 对象的概念
            38 4
            |
            2月前
            |
            缓存 JavaScript 前端开发
            JavaScript中数组、对象等循环遍历的常用方法介绍(二)
            JavaScript中数组、对象等循环遍历的常用方法介绍(二)
            40 1
            |
            2月前
            |
            缓存 JavaScript 前端开发
            深入了解JavaScript的闭包:概念与应用
            【10月更文挑战第8天】深入了解JavaScript的闭包:概念与应用
            |
            2月前
            |
            存储 JavaScript 前端开发
            js中函数、方法、对象的区别
            js中函数、方法、对象的区别
            20 2
            |
            2月前
            |
            JavaScript 前端开发 大数据
            在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
            在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
            30 0
            |
            2月前
            |
            前端开发 JavaScript 程序员
            【从前端入门到全栈】Node.js 之核心概念
            【从前端入门到全栈】Node.js 之核心概念