前端 JS面向对象 原型 prototype

目录

一、问题引出

二、prototype原型对象

三、小结

四、constructor

五、__proto__对象原型

六、原型链


一、问题引出

由于JS的构造函数存在内存浪费问题:

javascript 复制代码
    function Star(name,age){
       this.name=name
       this.age=age
       this.sing=function () {
           console.log("唱歌!")
       }
   }
   let star01=new Star("Jack",18)
   let star02=new Star("Mark",20)
   console.log(star01.sing==star02.sing)

打印:不同实例对象的动态方法是不同的,会开出新的内存区域用于存储相同的方法。

对此问题,提出了原型处理方法。

二、prototype原型对象

我们可以将不变的方法直接定义在prototype属性中,以减少内存开销。

对上面的问题代码进行优化:

javascript 复制代码
    function Star(name,age){
       this.name=name
       this.age=age
   }
   Star.prototype.sing=function (){
       console.log("唱歌!")
   }
   let star01=new Star("Jack",18)
   let star02=new Star("Mark",20)
   console.log(star01.sing==star02.sing)

打印:可以看到两个实例对象的该方法是同一个,证明都使用了同一个原型里的方法,没有新开内存拷贝。

三、小结

1、公共属性写到构造函数里;

2、公共函数写到prototype原型对象里;

3、构造函数里的this就是指向实例化的对象;

4、原型对象里的this还是指向实例化的对象。

四、constructor

prototype里的属性constructor属性就是帮原型确定它的构造函数是谁,如,构造函数Star的prototype里的constructor属性就是指向Star构造函数的。

作用:指向原型对象的构造函数。

javascript 复制代码
    function Star(){

   }

   console.log(Star.prototype)
   Star.prototype={
       sing:function (){
           console.log("唱歌")
       },
       dance:function (){
           console.log("跳舞")
       }
   }
   console.log(Star.prototype)

打印:没构造前,有constructor属性,构造后没有了

可以看到,上面这种写法直接给prototype赋值了新值,没有了constructor对象标识,正确写法应该是:

javascript 复制代码
    function Star() {

    }

    console.log(Star.prototype)
    Star.prototype = {
        //重新指回这个原型的构造函数 Star
        constructor: Star,
        sing: function () {
            console.log("唱歌")
        },
        dance: function () {
            console.log("跳舞")
        }
    }
    console.log(Star.prototype)

打印:

五、__proto__对象原型

每个实例化的对象都有一个__proto__,而这个__proto__就是指向构造函数的prototype对象的。这样一来,每个实例化对象都可以访问prototype里的数据了。

1、这是一个只读属性;

2、

javascript 复制代码
    function Star() {

    }
    const star01=new Star()
    console.log(star01.__proto__ === Star.prototype)

打印:这里可以看到__proto__指向的是构造函数的原型对象

此外,__proto__实例化对象的原型中也有constructor,并且是指向prototype原型对象中的constructor的。

六、原型链

只要是对象就是__proto__,prototype对象中也有__proto__属性,我们按照prototype的__proto__可以一级一级的指向,到最顶层Object.prototype.__proto__指向为null。

使用场景:比如某个对象需要调用一个方法,而这个方法在当前对象里没有,就会向上一级查找是否有该方法,若仍然没有再往上寻找prototype里是否有该方法,依次类推,直至到顶层prototype里查找,指向为null时结束查找。

可以通过instanceof来判断对象是否在一个原型链上。

相关推荐
孔令飞4 小时前
Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中指针引用Go中
前端
可乐鸡翅yeah_5 小时前
hls.js 缓冲区参数 maxBufferLength、maxBufferSize 通俗讲解与业务调参
开发语言·javascript·ios·音视频·safari·m3u8
溪语流沙5 小时前
【Web全栈进阶】PostgreSQL上手:Docker跑库 + 把早报站从SQLite迁过去
前端·docker·postgresql
IT_陈寒5 小时前
SpringBoot自动配置的坑:你以为的捷径可能是弯路
前端·人工智能·后端
paopaokaka_luck5 小时前
高校社团管理(AI辅助任务分配、协同过滤算法推荐、ECharts数据可视化、活动参与闭环、校园交流与反馈、器材借还管理)
java·前端·javascript·spring boot·数据分析·echarts
500845 小时前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
薛一半5 小时前
React-Redux三重优化实战揭秘
javascript·vue.js·react.js
Dovis(誓平步青云)5 小时前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
福兮说16 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理16 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程