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

简介: 相信很多小伙伴学习了javascript,但是对于对象只是有一个初步的认识,并且对于对象的原型和原型链之类的概念还没有很好的认识吧,本系列带你们一步步了解对象。一共13000+的字,我会分成几篇文章发布,我真的废了很多很多的心思,希望你们耐心的看完,并且能有深一层的理解。

一、对象的定义


对象是JavaScript的基本数据类型,对象内部是由一个个的名/值对组成的,例如下面我们常见的。


    {  name: '张三',  fn: function() { return 1 }}


    在JavaScript中,对象一共有三类,分别是:


    1. 内置对象:是由ECMAScript定义的对象或类。例如数组 Array 、函数 Function 、日期 Date 、正则表达式 RegExp


    1. 宿主对象:由JavaScript解释器所嵌入的宿主环境定义的。例如浏览器提供的对象 Window 、Document


    1. 自定义对象:是由用户写的JavaScript代码创建的对象。例如let obj = {}


    二、对象的创建


    创建对象的方式一共有三种,分别是:


    1. 对象直接量


    1. 通过new创建对象


    1. 通过Object.creat()创建对象


    • 对象直接量


    这种创建方式是我们最常见的,也是最常用的


      let obj1 = {}      //创建了一个空的对象let obj2 = {     //创建了有一个属性为name,值为张三的对象  name: '张三'}


      这种方式创建对象有一种缺点,比如在一个会重复调用的函数里,用了对象直接量的方式创建对象, 会重复创建很对的新对象,并且每次创建的对象的属性值也有可能不同。所以在实际应用中,如果遇到此类情况,尽量避免使用对象直接量的方式创建对象。


      • 通过new创建对象


      这种创建对象的方式,一般都是一个new运算符后面跟随一个函数调用,并且该函数有一个名字,叫做构造函数,顾名思义,就是用于构造创建一个对象。


        let arr = new Array()let data = new Date()


        这几个都是通过new调用了一个内置对象的构造函数,创建了新的对象实例,我们其实也可以自己定义一个构造函数,然后也通过new的方式来调用我们自定义的构造函数来创建一个对象实例,例如


          function MyObj() {  }let obj = new MyObj()    //成功调用构造函数 MyObj,创建了一个对象


          • 通过Object.create()创建对象


          这种方式是ES5中规定的新的创建对象的一种方式,只需要简单的传一个原型对象,即可创建对应的新的对象,例如


            let obj = Object.create({x:1, y:2})  //{x:1, y:2}是obj的原型


            三、对象的原型以及原型链


            刚在讲解创建对象的方法时,我们在介绍Object.creat()时,提到了原型的概念,在这里我们就来解释一下,什么是对象的原型。


            每一个对象(除了null)都和另一个对象有关联,“ 另一个对象 ” 就叫做原型。在这里我们可以做个形象的比喻,将原型比作一家餐饮店,将对象比作这家餐饮店的加盟店,这样理解起来就很容易了,我们创建了一个对象,就相当于我们开这家餐饮店的加盟店,并且我们的食材配方 、经营方法都是来自于这家加盟店,所以这里我们可以引入继承的概念,说是加盟店继承于这家餐饮店。


            在JavaScript中,绝大部分的对象都有一个共同的原型,他就是 Object.prototype ,也就是说 Object.prototype 是最原始的那家餐饮店,而非加盟店。


            每个函数的内部都有一个属性,叫做 prototype,他表示该函数的原型对象,例如


              //先写一个构造函数function MyObj() {  //这里暂时先不写任何代码}console.log(typeof MyObj)   //  functionconsole.log(typeof MyObj.prototype)  // Object


              从这个例子中可以看出,MyObj.prototype 返回的是一个对象类型的值,所以这就表示了它是该构造函数的原型对象。


              每个对象(除了null)都有一个属性——__proto__ ,该属性表示的是该对象的原型,我们来举两个例子,这两个例子是分别不同方式创建对象后,展示他们各自的原型


              • 用对象直接量创建的对象的原型


              let arr = []                          //对象直接量创建对象console.log(arr.__proto__ === Array.prototype)    //  trueconsole.log(arr.__proto__.__proto__ === Object.prototype)  //trueconsole.log(arr.__proto__.__proto__.__proto__)  // null


              arr.__proto__ 表示的是arr这个对象的原型,而我们都知道对象直接量其实是一种语法糖的写法,在这个例子中 let arr = [] 间接调用了 new Array ,所以我们可以通过 Array.prototype 来表示 Array 这个构造函数的原型对象, 将 arr.__proto__Array.prototype 做比较,发现它俩相等,所以 arr 的原型就是构造函数Array的原型对象。


              那么 arr.__proto__.__proto__ 是为了表示 arr 的原型(Array.prototype)的原型,因为我们上面说过,绝大多数的对象都有一个共同的原型 Object.prototype , 所以我们判断一下 Array.prototype 的原型是否就是 Object.prototype,从结果来看,确实是的。


              最后我们再去寻找 Object.prototype 的原型(arr.__proto__.__proto__.__proto__)就找不到了,因为 Object.prototype 我们看作是一家餐饮店的源头啊,他并不是谁的加盟店,所以最终返回 null。


              在这里我们就可以引入一个概念,叫做原型链。顾名思义,就是一条链子上有很多的原型,如图


              2826e6c06e4ded83b841b2bdfda31a99.png


              • 通过Object.create()创建对象


              let arr = Object.create({x:1, y:2})console.log(arr.__proto__)          // {x:1, y:2}console.log(arr.__proto__.__proto__ === Object.prototype) // trueconsole.log(arr.__proto__.__proto__.__proto__)    // null


              在第三种创建对象方式中,我们说到,用Object.create()创建对象,只需要传入一个原型对象,就可以创建一个继承于该原型对象的新对象。所以 arr 的原型(arr.__proto__)就是我们传入的那个对象,即 {x:1, y:2}


              arr.__proto__.__proto__ 返回的是 {x:1, y:2} 的原型。我们都知道{x:1, y:2} 这样的对象是通过对象直接量创建的,所以他其实是通过 new Object() 来创建的对象, 那么 {x:1, y:2} 的原型就为 Object.prototype 了。


              同样的, Object.prototype 没有原型,所以最后返回 null 。


              此时的原型链是这样的,如图


              855826cc80aac56cbfe95ebf91976348.png


              好了,因为【对象】的概念较多,所以今天的文章就讲到这里,之后我会继续更新,欢迎大家继续追更~

              相关文章
              |
              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 之核心概念