zoukankan      html  css  js  c++  java
  • JS

    感觉原型真是 JS 中非常复杂的一环。看 MDN 的文档某些地方也不是写的很清楚,下面写一些我对于原型的理解,如有错误望大家指出。

    感觉prototype[[Prototype]]挺容易混的,看 ES 的文档时也是在看到prototype.constructor时很蒙。

    根据我的经验prototype一般只有构造函数(函数)有,毕竟她可以创建对象(实例),其他对象,数组,字符串什么的没有必要有她。

    所有的的对象都有自己的原型链([[Prototype]]),

    她会继承(指向)其构造函数的prototype

    她的构造函数的[[Prototype]]会继承(指向)其构造函数的prototype

    她的构造函数的[[Prototype]]会继承(指向)其构造函数的prototype

    她的构造函数的[[Prototype]]会继承(指向)其构造函数的prototype,

    她的构造函数的[[Prototype]]会继承(指向)其构造函数的prototype

    。。。

    最终指向 null 结束。

    这样就和类一样了。

    prototype

    对象的prototype 属性表示她的原型,该属性里面包含着可以被 “继承” 的属性。(一般只有函数自带个属性)

    var foo = function(){}
    foo.prototype.bar = 666;
    
    // foo对象
    // {
    //     ...
    //     prototype: {
    //         ...
    //         bar: 666
    //     }
    // }
    

    prototype.constructor

    对象的prototype 属性里面有个特殊的属性constructor ,她是指向该对象的指针(这里可能有误 T_T )。(一般只有函数自带个属性)

    var foo = function(){}
    foo.prototype.bar = 666;
    
    // foo对象
    // {
    //     ...
    //     prototype: {
    //         ...
    //         constructor: foo,
    //         bar: 666
    //     }
    // }
    

    prototype.[[Prototype]]

    对象的prototype 属性里面还有个特殊的 "属性"[[Prototype]] ,可以用来模拟继承,她指向该对象的prototype 属性的继承下来的原型(指向该对象继承的原型的prototype属性的指针)。

    [[Prototype]] 也叫 prototype.__proto__

    对象的构造函数的原型(指向创建该对象的函数的prototype属性的指针)。(一切对象都有这个虚拟指针)

    Object.prototype.proto - JavaScript | MDN

    [[Prototype]].constructor

    对象的构造函数的原型的构造器(指向创建该对象的函数的prototype属性中的constructor属性的指针)。(一切对象都有这个虚拟指针)

    关系对比

    // Person
    var Person = function (name) {
        this.name = name;
        this.canTalk = true;
    };
    
    Person.prototype.greet = function () {
        if (this.canTalk) {
            console.log('Hi, I am ' + this.name);
        }
    };
    
    // Employee
    var Employee = function (name, title) {
        Person.call(this, name);
        this.title = title;
    };
    
    // subclass extends superclass
    Employee.prototype = Object.create(Person.prototype);
    Employee.prototype.constructor = Employee;
    
    Employee.prototype.greet = function () {
        if (this.canTalk) {
            console.log('Hi, I am ' + this.name + ', the ' + this.title);
        }
    };
    
    // instantiation
    var joe = new Person('Joe');
    var bob = new Employee('Bob', 'Builder');
    // call function
    joe.greet();
    bob.greet();
    
    // 直接打印
    console.log(Person, Employee, joe, bob)
    // prototype:当前对象的原型对象(实例 joe 和 bob 没有prototype)
    console.log(Person.prototype, Employee.prototype, joe.prototype, bob.prototype)
    // __proto__:返回当前对象构造函数的原型(代表的是 Obj.[[Prototype]])
    console.log(Person.__proto__, Employee.__proto__, joe.__proto__, bob.__proto__)
    // constructor:返回当前对象构造函数的引用(代表的是 Obj.[[Prototype]].constructor)
    console.log(Person.constructor, Employee.constructor, joe.constructor, bob.constructor)
    
  • 相关阅读:
    oracle 分布式数据库
    oracle 触发器
    oracle 存储过程,函数和包
    oracle 回收站
    oracle PL/SQL程序设计
    oracle 使用 ALTER 操作列
    oracle 集合运算符
    软工实践作业(六)
    软工实践作业(五)
    软工实践作业(四)
  • 原文地址:https://www.cnblogs.com/jffun-blog/p/12046199.html
Copyright © 2011-2022 走看看