美文网首页
JavaScript 复习——原型链

JavaScript 复习——原型链

作者: 极客传 | 来源:发表于2019-02-14 22:03 被阅读0次

    JavaScript 原型链中的主要知识概念:原型,构造函数,实例,proto,prototype,instanceOf,constructor

    所有的对象在默认的情况下都有一个原型,并且继承该原型上的属性。原型也是一个对象,它自身也有一个原型。

    JavaScript 中没有对函数和构造函数进行区分。每一个函数都有一个 prototype (原型)属性,这个属性是一个指针,指向一个对象,即原型对象,原型对象上的属性和方法,能被函数的实例所共享

    构造函数通过 new 生成一个实例对象,该实例对象具有一个__proto__属性,指向原型对象。并且与其构造函数的 prototype 属性指向的是同一个对象。

    instanceOf 方法,用来判断对象是否为构造函数的一个实例。

    obj instanceof Object
    // 返回 true,false
    

    constructor 属性返回对象的构造函数。(返回值是函数的引用,不是函数名)

    创建对象的方式

    创建对象的三种方式:

    // 字面量
    var o1 = { name : "o1"};
    // 或
    var o1 = new Object({ name: "o1"});
    
    // 构造函数
    function M (name) {
      this.name = name;
    }
    var o2 = new M("o2");
    
    // Object.create()
    var o3 = Object.create({name: "o3"})
    
    console.log(o1)
    console.log(o2)
    console.log(o3)
    

    由打印结果可知,前两种方式创建的对象,其原型是 Object。Object.create(obj) 方法,会生成一个空对象,并将传入的参数对象 obj 作为该空对象的原型对象。

    原型链

    原型链:一个实例对象 A,是由构造函数基于原型对象创建的,通过 prototype 属性可查找到其原型对象 B,再往上查找,又有创造 B 的原型对象,以此类推,一直查找到 Object.prototype 为止,Object.prototype 是整个原型链的顶端。原型对象的查找,是通过 prototype__proto__ 属性来实现向上查找的。

    来自慕课网

    由上图可知,获取对象原型的方法有:

    var a = {}; 
    
     //Firefox 3.6, Chrome 5 and Safari 4 
    a.__proto__; //[object Object]   
    
     //all browsers 
     a.constructor.prototype; //[object Object]
    

    另外还可以利用 ES6 中的 Object.getPrototypeOf() 来获取对象的原型:

     //Firefox 3.6 and Chrome 5 
     Object.getPrototypeOf(a); //[object Object]   
    

    Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)

    一个构造函数的原型对象,其构造器即为构造函数本身。

    function M (name) {
      this.name = name;
    }
    var o2 = new M("o2");
    
    // M.prototype即为M的原型对象
    M.prototype.constructor === M // true,由于M为一个构造函数,M原型对象的构造器即为M
    
    // o2._proto_即为o2的原型对象
    o2.__proto__ === M.prototype // true
    

    函数才有 prototype 属性,由于函数也是对象,所以函数也有 __proto__ 属性。

    // 函数M,是构造函数Function的一个实例
    M.__proto__ === Function.prototype // true
    

    原型对象上的方法,可以被其实例使用。


    .

    instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置

    function M (name) {
      this.name = name;
    }
    var o2 = new M("o2");
    
    o2 instanceof M // true
    o2 instanceof Object // true
    
    o2.__proto__ === M.prototype // true,指向同一个原型对象
    M.prototype.__proto__ === Object.prototype // true
    

    Object.prototype 指向 o2 原型对象的原型(o2 的二阶原型对象),所以 o2 instanceof Object 为 true。
    .
    那么如何判断,一个实例对象,是构造函数的实例,还是继承自原型对象的实例呢?
    由原型链图可知,一个对象的原型通过 constructor 指向该对象的构造函数。

    o2.__proto__.constructor === M // true
    o2.__proto__.constructor === Object // false
    

    一个构造函数的原型对象,其构造器即为构造函数本身。

    .


    “在构造函数内的绑定操作优先级,永远高于在原型上的绑定操作优先级。”
    如,在构造函数内和原型上都定义了一个方法,构造器内的方法会覆盖原型上的方法。

    function Person () {
      this.name = 'jean'
    }
    
    Person.prototype.name = 'test'
    
    var man = new Person()
    console.log(man.name) // 'jean'
    

    在实际开发中,我们经常用 hasOwnProperty() 这个方法,来检查给定的属性在当前对象实例中(而不是实例的原型中)是否存在。因为利用普通 obj.key 的形式获取对象属性时,会先在对象本身获取该属性,若未查到,则到该对象的原型上去查找,一直向上查到 key 值或查到原型对象为 Object.prototype 为止。

    相关文章

      网友评论

          本文标题:JavaScript 复习——原型链

          本文链接:https://www.haomeiwen.com/subject/cksceqtx.html