• javascript 原型链


    我们每创建一个函数都会有一个 prototype属性,该属性是一个对象,原型对象中存在一个 constructor 属性,该属性值指向原函数

    function Person() {
    }
    console.log(Person.prototype);
    

    控制台输出内容:

    每个通过构造函数创建的实例默认都指向了这个原型对象 prototype

            function Person() {}
            Person.prototype.name = 'Tom'
            Person.prototype.sayName = function () {
                console.log(this.name);
            }
            const person1 = new Person()
            const person2 = new Person()    
            //通过构造函数创建的实例内部中,有一个属性指向原型对象
            console.log(person1.__proto__ === Person.prototype); //true
            console.log(person2.__proto__ === Person.prototype); //true
            也可以通过ES5 新增的一个方法来验证
            //Object.getPrototypeOf()  方法返回指定对象的原型(内部[[Prototype]]属性的值)。MDN
            console.log(Object.getPrototypeOf(person1) === Person.prototype); //true
            console.log(Object.getPrototypeOf(person1) === Person.prototype); //true
    

    prototype所指向的那个对象,为通过构造函数创建的实例,提供共享属性和方法的功能,
    示例1:

            function Person() {}
            Person.prototype.name = 'Tom'
            Person.prototype.sayName = function () {
                console.log(this.name);
            }
            const person1 = new Person()
            const person2 = new Person()
            //实例在获取一个方法或属性的时候。会先在自身寻找该属性或方法,如果自身不存在,会继续向上查找原型对象,找到后返回,如果没有找到则是 undefined
            function Person() {}
            const person1 = new Person()
            person1.sayName() //Tom
            person2.sayName() //Tom
            console.log(person1.sayName === person2.sayName); //true
    
    

    示例2:

            function Person (){}
            Person.prototype = {
                  name:"Tom",
                  sayName: function(){
                        log(this.name)
                  }
            }
            const person1 = new Person()
            person2.sayName() //Tom
    

    要注意的地方

    代码段 A:

            function Person() {}
            Person.prototype = {
                name: "Tom",
                sayHi: function () {
                    console.log("Hi --- " + this.name);
                }
            }
            const person1 = new Person()
            person1.sayHi() // Hi --- Tom
    

    这段代码中的实例对象,是在原型添加新方法和属性之后创建的,它可以访问到原型中的方法和属性

    下面这段代码中的实例,也是在原型中添加新方法和属性之前创建的,但是它却访问不到原型中定义的属性和方法
    代码段 B:

            function Person() {}
            const person1 = new Person()
            Person.prototype = {
                name:"Tom",
                sayHi: function () {
                    console.log("Hi --- " + this.name);
                }
            }
            person1.sayHi() //报错 Uncaught TypeError: person1.sayHi is not a function
    

    原因就在于, prototype 是一个指针,指针中存放的是原型对象的地址,这里假如存放的地址为 1000H ,那么在new实例的时候,实例对象中也包含一个指针,指向 prototype这个指针,这有点像C语言中的多级指针。在代码段 B中,new实例的时候,实例中的指针指向 prototype 指针, prototype 指针中存放的原型地址为 1000H,当代码运行到重写原型那一行,这时,原型对象的地址已经改变了 ,这里假如它改变的地址为 1001H,它里面存放了 name 属性 和 sayHi 方法。我们在之后,访问sayHi这个方法时,访问的还是之前 prototype 指针中存放的 1000H 这个地址中的原型对象。

    下图来自 js 高程 6.2 --157 页

  • 相关阅读:
    ORACLE数据库逐步解决ORA-12541、ORA-01034和ORA-27101、ORA-00119和ORA00132的过程
    Windows下MySQL主从复制的配置
    Windows下Git的使用
    spring boot 2 集成JWT实现api接口认证
    spring boot 2 全局统一返回RESTful风格数据、统一异常处理
    spring boot 2 + shiro 实现权限管理
    Java 密码加盐
    Java中往zip压缩包追加文件
    IntelliJ IDEA 安装、配置和使用Lombok插件
    大规模微服务单元化与高可用设计
  • 原文地址:https://www.cnblogs.com/freedomweb/p/12963256.html
Copyright © 2020-2023  润新知