Skip to content

JS基础-01:原型了解


在接触JS之前,我工作过程中基本都是采用Java、C#、C++开发,也就是面向对象编程,对于类、继承都很熟悉,所以在构建数据结构的时候,就会下意识的采用类来定义结构,而使用JS开发的时候,创建可以通过new 方法名来创建对象,定义属性和方法放到不同位置,会出现属于类的、属于实例的还是属于原型的?这让我搞得很懵逼,面向对象结构都定义在类上,没有这么复杂,为了搞清这些概念决定仔细学习一下。

原型


概要内容

  • 示例代码

    jsx
    function Parent(name){
        this.name = name;
    }
    
    let p1 = new Parent("xxx");
    
    //测试关系
    console.log("p1.constructor === Parent:" + (p1.constructor === Parent));//true
    console.log("Parent.constructor === Function:" + (Parent.constructor === Function));//true
    console.log("Function.constructor === Function:" + (Function.constructor === Function));//true
    
    console.log("Parent.__proto__ === Function.prototype:" + (Parent.__proto__ === Function.prototype));//true
    console.log("Parent.prototype.constructor === Parent:" + (Parent.prototype.constructor === Parent));//true
    
    console.log("p1.__proto__ === Parent.prototype:" + (p1.__proto__ === Parent.prototype));//true
    console.log("Parent.prototype.__proto__ === Object.prototype:" + (Parent.prototype.__proto__ === Object.prototype));//true
    console.log("Object.prototype.__proto__:" + (Object.prototype.__proto__));//null
    
    console.log("Object.prototype.constructor === Object:" + (Object.prototype.constructor === Object));//ture
    console.log("Object.constructor === Function:" + (Object.constructor === Function));//ture
    console.log("Object.prototype === Object.prototype:" + (Object.prototype === Object.prototype));//ture
    
    console.log("Object.__proto__ === Function.prototype:" + (Object.__proto__ === Function.prototype));//ture
    
    console.log("Function.__proto__ === Function.prototype:" + (Function.__proto__ === Function.prototype));//ture
    console.log("Function.prototype === Function.prototype:" + (Function.prototype === Function.prototype));//ture
    
    console.log("Function.prototype.__proto__ === Object.prototype:" + (Function.prototype.__proto__ === Object.prototype));//ture

    更多测试示例:https://github.com/yxw007/H5-Learn/blob/master/js/02_Proto.js

  • 图解关系:根据以上测试用例,得出一下关系图

    https://cdn.jsdelivr.net/gh/yxw007/BlogPicBed@master/img/20211107203334.png

    https://cdn.jsdelivr.net/gh/yxw007/BlogPicBed@master/img/20211105224752.jpg

  • 看图思路:

    • 看对象p的_proto流向:p1→Parent.prototype→Object.prototype→null(原型链)
    • 看constructor流向:p1→Parent()→Fuction (constructor指向构造方法)
    • 看Function的__proto:Parent()→Function.prototype、Object()→Function.prototype、Function()→ Function.prototype (方法._proto 都指向Function.prototype)
  • 结论:

    • proto、constructor 属性 是【对象】独有的,函数也是一种对象
    • prototype 属性 是【函数】独有的
    • proto : 对象父级原型(用来往原型链上级走)
    • 方法的最顶端是Function构造方法
    • proto 原型链的最顶端是null
    • Function 与 Function.proto 肯定有两条连线,Function.proto,Function.constructor
    • Parent的__proto__ 指向父类的原型

总结:数据结构定义

  • 实例属性:在构造方法中定义,通常用【this.名称 = 初始值】定义

    jsx
    function Animal(name){
     this.name = name
    }
    
    //es6
    //方式1:推荐方式
    class Animal{
     constructor(name){
      this.name = name
     }
    }
    
    //补充
    class Animal{
     material="材质",  // 说明:此种方式定义的属性material 也属于实例上的
     constructor(name){
      this.name = name
     }
    }
  • 原型属性和方法:

    jsx
    
    function Animal(){
    }
    
    Animal.prototype.live= "地球"
    Animal.prototype.move = function(){}
    
    //es6
    class Animal{
     move(){}
     get live(){
          return "地球";
      }
    }
  • 类上的属性和方法

    jsx
    class Animal {
      //类上的属性和方法
        static material = "材质"
        static sex(){
            return "未知"
        }
    }

...

以上:如发现有问题,欢迎留言指出,我及时更正

Released under the MIT License.