a315489687 2022-02-14 13:54 采纳率: 50%
浏览 89
已结题

菜鸟请教这个关于js原型链的demo


<script type="text/javascript">
    function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.say = function(){
        alert('Person的say');
    }
    Object.prototype.say = function(){
        alert('Object原型的say');
    }
    Function.prototype.say = function(){
        alert('Function原型的say');
    }    
    Function.say = function(){
        alert('Function的say');
    }
    Person.prototype.say = function() {
        alert(this.name);
    };
    let p = new Person('月初',16);
    p.say();
</script>

这个本站的demo
为什么弹出的是月初而不是“Person的say”,哪位帮忙解释下

  • 写回答

4条回答 默认 最新

  • 归来巨星 前端领域新星创作者 2022-02-14 14:10
    关注

    这样去说在一个对象实例化之前,这个对象其实也就是一个函数

    参照你的问题 为什么弹出的是 月初 而不是 “Person的say” ?

    首先你要考虑一个问题,在对象没有被实例化之前,他只是一个首字母大写的函数,那如果给函数直接定义一个 .方法的话找的是谁?

    万物不变起源 万物皆对象 抛去其他的一切因素 调用 Person.say() 寻找的层级先滤清 先找 Person.say -> Function.prototype.say -> Object.prototype.say, 你可以先这样去试一下

      <script type="text/javascript">
        function Person(name, age) {
          this.name = name;
          this.age = age;
        }
    
        Object.prototype.say = function () {
          alert("Object原型的say");
        };
        Function.prototype.say = function () {
          alert("Function原型的say");
        };
        Function.say = function () {
          alert("Function的say");
        };
        Person.prototype.say = function () {
          alert(this.name);
        };
        // Person.say = function () {
        //   alert("Person的say");
        // };
        // let p = new Person("月初", 16);
        Person.say(); // 寻找层级 Person.say -> Function.prototype.say -> Object.prototype.say
      </script>
    

    而如果你的对象实例化之后,这个时候其实他已经被new了,那么他就不再会是一个函数,而是一个对象,如果没有父实例,那么他的上级指向将不再会是 Function,参照下方

    <script type="text/javascript">
        function Person(name,age) {
            this.name = name;
            this.age = age;
        }
    
        Object.prototype.say = function(){
            alert('Object原型的say');
        }
        Function.prototype.say = function(){
            alert('Function原型的say');
        }    
        Function.say = function(){
            alert('Function的say');
        }
        // Person.prototype.say = function() {
        //     alert(this.name);
        // };
        Person.say = function(){
            alert('Person的say');
        }
        let p = new Person('月初',16);
        p.say(); // alert('Object原型的say');
    </script>
    </html>
    

    简单的说 Person.prototype.say != Person.say 一个是在其对象原型上挂载say方法,一个是在其方法上挂载一个say方法,而原型链查找的是 prototype 所以会出现你所说的找不到的问题

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月23日
  • 已采纳回答 2月15日
  • 创建了问题 2月14日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改