zoukankan      html  css  js  c++  java
  • 深入理解JavaScript原型链

    前言

    最近碰到一个题,大家可以试下。

    Object.prototype.a = function() {
        console.log("aaa "+this.name);
    };
    
    Function.prototype.b = function() {
        console.log("bbb "+this.name);
    };
    
    function Person(name) {
        this.name = name;
    }
    
    var person = new Person("China");

    问:person.a() person.b()分别返回什么?


    资料引用

    上述题目考察的是JavaScript原型链的问题。我们引用《JavaScript高级程序设计(第三版)》中关于原型对象的相关叙述。
    - 列表内容

    无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
    当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第5版中管这个指针叫[[Prototype]]。脚本中没有标准的方式访问[[Prototype]],但浏览器在每个对象上都支持一个属性__proto__。该连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。

    分析问题

    通过上面的说明,我们再来看下那个题目。构造函数Person有个prototype属性,指向Person的原型对象。而Person.prototype也是一个对象,则内部有[[Prototype]]指针,指向构造函数的原型对象,而该对象的构造函数则是Object()。Person.prototype.__proto__ -----> Object.prototype。而实例person的内部指针[[Prototype]]则指向构造函数Person的原型Person.prototype。

    解决问题

    通过上面的分析,我们就构造了一条原型链:
    person.\__ptoto__ -----> Person.prototype
    所以person.a()通过原型链查找,最终找到Object.prototype中的方法a,控制台输出aaa China,而没有找到方法b,所以会报错,显示TypeError: undefined is not a function

    深入理解

    在问题中,构造函数Person同样也是Function的一个实例,所以Person.__proto__ —–> Function.prototype。而构造函数继承的是Prerson.prototype,而不是Person.\__proto__。
    可以通过isPrototypeOf()确定某个对象是否是另一个对象的原型。
    Person.prototype.isPrototypeOf(person); //true
    另外,ECMA5增加了一个方法Object.getPrototypeOf()来代替__proto__,返回[[Prototype]]的值。
    对于操作符instanceof,判断某个对象是否属于某个构造函数,就是通过判断该构造函数的prototype属性是否存在对象的原型链上。
    Person instanceof Function; //true
    而虽然Object.getPrototypeOf(Function)返回结果是function Empty(){},但
    Function instanceof Object仍然返回true,则只能算是甲鱼的臀部——规定啦。
    另外,ECMA5提供了一个继承方法Object.create(proto, [ propertiesObject ]),创建一个拥有指定原型和若干个指定属性的对象。

    // 只继承Person.prototype 而不实例化name属性
    var person = Object.create(Person.prototype);
    
    //但下面仍为true
    person instanceof Person;
  • 相关阅读:
    给jdk写注释系列之jdk1.6容器(9)-Strategy设计模式之Comparable&Comparator接口
    给jdk写注释系列之jdk1.6容器(8)-TreeSet&NavigableMap&NavigableSet源码解析
    给jdk写注释系列之jdk1.6容器(7)-TreeMap源码解析
    给jdk写注释系列之jdk1.6容器(6)-HashSet源码解析&Map迭代器
    给jdk写注释系列之jdk1.6容器(5)-LinkedHashMap源码解析
    给jdk写注释系列之jdk1.6容器(4)-HashMap源码解析
    给jdk写注释系列之jdk1.6容器(3)-Iterator设计模式
    给jdk写注释系列之jdk1.6容器(2)-LinkedList源码解析
    给jdk写注释系列之jdk1.6容器(1)-ArrayList源码解析
    留言板
  • 原文地址:https://www.cnblogs.com/qingguo/p/5686291.html
Copyright © 2011-2022 走看看