JavaScript的原型及原型链

作者: BarryLiu1995 | 来源:发表于2017-08-04 11:27 被阅读112次

引言:javascript王国的一次旅行,一个没有类的世界怎么玩转面向对象? 一文中我们提到了在没有类概念的 JavaScript 语言中是通过原型来实现面向对象的继承特性。只要运用得好,这种基于原型的 JavaScript 继承模型比传统的类继承还要强大。所以我们还需详细学习一下原型的知识


JavaScript 的对象

JavaScript 是基于对象的面向对象语言。因此在这里的“对象”既可以是普通对象(Object),也可以是函数对象(Function)。JS 抛弃了 Java 的类概念,而 Java 的继承恰恰是通过类来实现的。那么 JS 没有类的概念,就使用了“原型”的概念来实现继承。

字面量原型及原型链

JS 可通过字面量构造对象。为了实现继承,对象里面有个_proto_属性可以指向该对象的父对象。这个父对象就是所谓的“原型”。

var animal = {
  name: '动物',
  eat: function(){
    console.log(this.name + " is eating");
  }
};

animal.eat();     // animal is eating

var dog = {
  name: '狗',
  _proto_: animal
};

var cat = {
  name: '猫',
  _proto_: animal
};

dog.eat();        // 狗 is eating
cat.eat();        // 猫 is eating

由上面代码我们可以看出:dog 和 cat 对象的原型都是 animal。但是 dog 和 cat 对象都没有定义 eat()方法,那怎么可以调用呢?其实当eat方法被调用的时候,先在自己的方法列表中寻找, 如果找不到,就去找原型中的方法, 如果原型中找不到, 就去原型的原型中去寻找...... 最后找到Object那里, 如果还找不到, 那就是未定义了。这几个对象通过_proto_属性建立一个原型链!

构造函数原型链

由上面的代码和示意图可看出这个所谓的构造函数 Student 其实就是一个幌子啊, 每次去new Student的时候,确实会创建一个对象出来( andy 或者 lisa ) , 并且把这个对象的原型指针(_proto_)指向 Student.prototype 这个对象,这样一来就能找到sayHello()方法了。我们应该还知道上面的构造函数Student()对象(JS 中函数也是对象)会创建一个 prototype 对象(Student.prototype),而 new 出来的实例对象例如 andy 和 lisa 是没有这个 prototype 对象,但是他会有个 proto 属性(_proto_)指向这个构造函数对象的 prototype 对象,从而构成原型链。实例对象其实是通过原型对象与构造函数取得联系的。为了让 Java、C#、C++ 程序员降低学习成本,JavaScript 提供了语法糖:

class Student {
  constructor(name){
    this.name = name;
  }
  sayHello(){
    console.log("Hi, I'm "+this.name);
  }
}

var andy = new Student("andy");   
andy.sayHello();                     //Hi, I'm andy

Object.create()

var a = Object.create(null);
console.log(a);                 //{}
a.name = 'Zhiyu';
var b = Object.create(a);
console.log(b);                 //{}
console.log(b.name);            //Zhiyu

上面我们可以看出该方法是创建一个空对象,空对象的原型是create()参数。此时创建的空对象会有个(_proto_)属性指向方法参数,这样也可以构成一个原型链。

总结

  1. JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做 _ proto_ 的内置属性,用于指向创建它的函数对象的原型对象 prototype
  2. 原型和原型链是 JS 实现继承的一种模型
  3. 原型链是靠 _proto _ 形成的,而不是 prototype
  4. 所有的原型对象都有 constructor 属性,该属性对应创建所有指向该原型的实例构造函数
  5. 函数对象和原型对象通过 prototype 和 constructor 属性进行相互关联

参考

最后是广告时间,我的原创博文将同步更新在三大平台上,欢迎大家点击阅读!谢谢

刘志宇的新天地

简书

稀土掘金

相关文章

  • JavaScript面试考点之原型及原型链

    1、JavaScript原型及原型链 1)原型 JavaScript是一种基于原型的语言,即每一个对象拥有一个原型...

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • 原型、原型链

    (什么是原型、原型链?有什么作用) JavaScirpt深入之从原型到原型链 图解 Javascript 原型链 ...

  • js原型、原型链、继承的理解

    一、原型、原型链 原型是Javascript中的继承的基础,JavaScript的继承主要依靠原型链来实现的。 原...

  • javascript原型链及继承的理解

    javascript:void(null)# 原型链及继承的理解 定义函数 继承 继承构造函数 继承静态属性 继承原型链

  • 【javascript】继承

    javascript只支持实现继承,而且继承主要是依靠原型链来实现的。 原型链 javascript将原型链作为实...

  • javascript碎片知识001

    javascript中的对象(原型,原型链) 什么是原型? 原型是JavaScript中的继承的基础,JavaSc...

  • JavaScript原型及原型链

    一、原型 原型是 ECMAScript 实现继承的过程中产生的一个概念。 继承: java 中:指在已有的一个类基...

  • JavaScript 原型及原型链

    一:prototype属性 这是一个显式原型属性,只有函数才拥有该属性,基本上所有函数都有这个属性。 protot...

  • javaScript原型链

    javaScript原型链概念JavaScript之继承(原型链)数据结构var Person = functio...

网友评论

    本文标题:JavaScript的原型及原型链

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