js进阶笔记之原型,原型链

目录

1、原型对象

[constructor 属性](#constructor 属性)

对象原型

2、原型链

3、instanceof

4、原型继承


1、原型对象

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。

面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。

面向过程开发(关注具体实现步骤)

面向对象开发(分析涉及的对象,指挥对象完成)----- 封装、继承、多态

原型为了共享公共的成员 prototype

原型:JS为每个构造函数提供一个属性prototype(原型),它的值是一个对象,prototype也叫原型对象

构造函数通过原型分配的函数是所有对象所 共享的。

  • JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象

  • 这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存

  • 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。

  • 构造函数和原型对象中的this 都指向 实例化的对象

javascript 复制代码
    <script>
      // 面向过程开发(关注具体实现步骤)
      // 面向对象开发(分析涉及的对象,指挥对象完成任务) - 封装、继承、多态
      function Cat(name, age) {
        this.name = name
        this.age = age
        //  给实例添加eat方法,将来每一个对象都有这个eat方法,造成空间浪费
        // this.eat = function () {
        //   console.log('猫吃老鼠')
        // }
      }

      // 给Cat原型添加公共的属性或方法,这样所有new出来的实例都可以访问
      Cat.prototype.eat = function () {
        console.log('猫吃老鼠')
      }

      Cat.prototype.nation = 'china'

      const cat1 = new Cat('加菲猫', 3) // {name:  '',age: ,eat}
      const cat2 = new Cat('银渐层', 4) // {name: '',age: ,eat() {}}
      console.log(cat1.age)
      console.log(cat1.nation)
      cat1.eat()
      cat2.eat()
      console.log(cat1.eat === cat2.eat) // true

      // 原型为了共享公共的成员  prototype
      // 原型: JS为每个构造函数提供一个属性prototype(原型),它的值是一个对象,prototype也叫原型对象
      console.log(Cat.prototype)
      console.log(Cat.prototype.constructor === Cat) // true

      // function f() {}
      // console.log(f.prototype)
    </script>

constructor 属性

constructor 属性,原型对象的属性---->原型对象的构造函数

javascript 复制代码
 <script>
      // constructor属性,原型对象的默认属性->原型对象的构造函数
      //  Array.prototype.constructor === Array
      console.log(Array.prototype.constructor === Array) //  true
      const arr = [] //  new  Object()
      console.log(arr.constructor === Array) // true
      console.log(arr.constructor === Array.prototype.constructor) // true
      console.log(arr.constructor) // 访问arr数组对象的constructor,会到原型去访问

      console.log(Object.prototype.constructor) // Object ;
      const obj = {}
      console.log(obj.constructor) // Object
      const obj2 = { a: 1 }
      console.log(obj.constructor === obj2.constructor) // true
    </script>

访问成员的查找原则

访问对象成员的原则:先查找自己身上有没有,有的话就使用,没有去原型查找

javascript 复制代码
  <script>
      function Cat(name, age) {
        // this.name = name
        this.age = age
      }

      Cat.prototype.eat = function () {
        console.log('猫抓老鼠')
      }

      Cat.prototype.name = '亚洲猫王'
      const cat = new Cat('小花', 3) // {name: '小花', age: 3}
      // 访问对象成员的原则: 先查找自己身上有没有,有的话就使用,没有去原型查找
      console.log(cat.name)
    </script>

对象原型

对象都会有一个属性__proto__ 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype

proto 对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数

三者关系

构造函数 原型 原型对象

每个对象都有一个_proto_属性(非标准属性->ES6标准属性),指向原型对象,它与[[Prototype]]等价

2、原型链

对象访问成员的机制

1、首先查找自身有没有,有就就近原则使用

2、自身没有该成员,通过_proto_找到原型对象,看原型对象上有没有,有就执行

3、假如原型对象上也没有,再找原型对象的_proto__,一直找到0bject.prototype

4、一直找到Object. prototype,找不到就undefined

3、instanceof

typeof 检测数据类型 不能精准的检测引用类型

instanceof 实例对象 instanceof 构造函数

判断构造函数的原型对象是不是在实例对象的原型链上

javascript 复制代码
<script>
      //  // typeof 检测数据类型
      // string number boolean
      console.log(typeof []) //'object'
      console.log(typeof {}) // 'object'
      console.log(Array.prototype) // 数组原型也提供toString(),自己原型的方法是拼接字符串
      // console.log([1, 2, 3].toString()) // [object Array]
      console.log({}.toString()) // [object Object]
      console.log(Object.prototype.toString.call([])) // call调用函数

      // instanceof 实例对象 instanceof  构造函数
      // 判断构造函数的原型对象是不是在实例对象的原型链上
      console.log([] instanceof Array) // true
      console.log([] instanceof Object) // true
      console.log({} instanceof Array) // false
    </script>

4、原型继承

继承方式:构造函数继承、原型继承、组合继承、。。。。

原型继承-----> 儿子的原型指向父实例对象,这样父实例对象的成员就可以实现继承

缺点:继承的引用类型属性就一份

javascript 复制代码
    <script>
      // 继承
      const person = {
        ears: 2,
        eat: function () {
          console.log('eating')
        },
        hobby: ['reading', 'running'],
      }

      function Student(name, age) {
        this.name = name
        this.age = age
      }

      // 让Student的原型指向person
      Student.prototype = person
      Student.prototype.constructor = Student
      Student.prototype.study = function () {
        console.log('study hard!!!')
      } 

      /*

         {
           ears, eat,  hobby,constructor, study
         }
      */
      const s1 = new Student('zs', 16)
      const s2 = new Student('zw', 24)
      console.log(s1.ears)
      s1.study()
      s1.eat()
      s2.hobby.push('coding')
      console.log(s2.hobby)
      console.log(s1.hobby)
      console.log(person)
    </script>
相关推荐
邝邝邝邝丹几秒前
React学习———Immer 和 use-immer
javascript·学习·react.js
魔术师ID4 分钟前
vue2.0 组件生命周期
前端·javascript·vue.js·学习·visual studio code
胜玲龙17 分钟前
单点登录是是什么?具体流程是什么?
java·服务器·前端
小浪学编程20 分钟前
C#学习9——接口、抽象类
前端·学习·c#
Dontla21 分钟前
《黑马前端ajax+node.js+webpack+git教程》(笔记)——ajax教程(axios教程)
前端·ajax·node.js
打小就很皮...26 分钟前
基于 Vue 和 Node.js 实现图片上传功能:从前端到后端的完整实践
前端·vue.js·node.js
面包资料屋38 分钟前
整理了 2009 - 2025 年的【199 管综真题 + 解析】PDF,全套共 34 份文件
开发语言·javascript·pdf
ange201743 分钟前
前端工程的相关管理 git、branch、build
前端·git
潇-xiao44 分钟前
Qt 信号和槽-核心知识点小结(11)
c++·笔记·qt
夏季疯1 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.4.6)
java·笔记·学习