https://segmentfault.com/a/1190000002900676

介绍

和java这种基于类(class-base)的面向对象的编程语言不同,javascript没有类这样的概念,但是javascript也是面向对象的语言,这种面向对象的方式成为 基于原型(prototype-base)的面向对象。虽然说ES6已经引入了类的概念来作为模板,通过关键字 “class” 可以定义类,但ES6的这种写法可以理解为一种语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。如果要理解基于原型实现面向对象的思想,那么理解javascript中得三个重要概念: 构造函数(constructor)、原型(prototype)、原型链(prototype chain) 对帮助理解基于原型的面向对象思想就显得尤为重要。下面就重点介绍一下这几个概念。

javascript对象结构图

先来看一张来自mollypages.org 的javascript对象的结构图,下面的例子都按照这张图阐述。

构造函数(constructor)和原型 (prototype)

构造函数是用来初始化对象的,每个构造函数都有一个不可枚举的属性,这就是原型(prototype).并且,每个prototype 都包含一个包含了不可枚举属性的constructor属性,这个属性始终会指向构造函数。

 function Foo(){};
console.log(Foo.prototype.constructor === Foo); // true

原型链(prototype chain)

使用new实例化的原型

每个被new实例化的对象都会包含一个__proto__ 属性,它是对构造函数 prototype 的引用。

  function Foo(){};
var foo = new Foo();
console.log(foo.__proto__ === Foo.prototype); // ture
  function Foo(){};
console.log(Foo.prototype.__proto__ === Object.prototype); // true

上面返回true 的原因是Foo.prototype 是Object预创建的一个对象,是Object创建的一个实例,所以,Foo.prototype.__proto_ 是Object.prototype的引用。

我们可以来看一下原型链的脉络。

函数(function)对象的原型

在javascript中,函数是一种特殊的对象,所有的函数都是构造函数 Function 的实例。

  function Foo() {};
console.log(Foo.__proto__ === Object.prototype); //false
console.log(Fool.__proto__ === Function.prototype); // true

从上面可以看出,函数Foo.__proto_ 指向到 Function.prototype, 说明函数 Foo 是 Function的一个实例。

 function Foo(){};
console.log(Foo.__proto__ === Function.prototype); //true
console.log(Foo.prototype.__proto__ === Object.prototype);//true

Foo.prototype 是Object预定义的对象,构造函数为Object,所以__proto__指向 Object.prototype

从上面的图我们可以看出, Object、Function、Array 等这些函数,他们的构造函数都是 Function 的实例。

基于原型链的继承

有了上面的基础知识以后,我们就可以自己去基于原型链去封装对象,实现javascript的继承。先来看下面一个例子。

运行上面的例子,输入 cat init 和 animal eat,说明cat 继承了 Animal.prototype.eat 的方法。

我们来分析一下代码。

1、Animal 的prototype中定义了 eat方法。
2、将Empty.prototype 指向 Animal.prototype , 所以 Empty.prototype 中也存在eat方法.
3、Cat.prototype == new Empty(),所以 Cat.prototype.__proto_ === Animal.__proto_.
4、重新为Cat指定constructor为Cat,否则Cat不存在constructor。

这样就完成了继承,原型链是这样的:

这样我们用原型链的方式实现了一个简单的继承方式。

Javascript面向对象编程的更多相关文章

  1. JavaScript面向对象编程学习笔记

    1  Javascript 面向对象编程 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例 ...

  2. 快速学习JavaScript面向对象编程

    到处都是属性.方法,代码极其难懂,天哪,我的程序员,你究竟在做什么?仔细看看这篇指南,让我们一起写出优雅的面向对象的JavaScript代码吧! 作为一个开发者,能否写出优雅的代码对于你的职业生涯至关 ...

  3. 深入理解Javascript面向对象编程

    深入理解Javascript面向对象编程 阅读目录 一:理解构造函数原型(prototype)机制 二:理解原型域链的概念 三:理解原型继承机制 四:理解使用类继承(继承的更好的方案) 五:建议使用封 ...

  4. 【转】Javascript 面向对象编程(一):封装

    原文链接:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html Javascript ...

  5. Javascript 面向对象编程(一):封装 by 阮一峰

    <Javascript高级程序设计(第二版)>(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Java ...

  6. 转:javascript面向对象编程

    作者: 阮一峰 日期: 2010年5月17日 学习Javascript,最难的地方是什么? 我觉得,Object(对象)最难.因为Javascript的Object模型很独特,和其他语言都不一样,初学 ...

  7. 探讨javascript面向对象编程

    (个人blog迁移文章.) 前言: 下面将探讨javascript面向对象编程的知识. 请不要刻意把javascript想成面向对象编程是理所当然的. javascript里面,对象思想不可少,但是不 ...

  8. JavaScript面向对象编程(一)原型与继承

    原型(prototype) JavaScript是通过原型(prototype)进行对象之间的继承.当一个对象A继承自另外一个对象B后,A就拥有了B中定义的属性,而B就成为了A的原型.JavaScri ...

  9. JavaScript面向对象编程(二)构造函数和类

    new关键字和构造函数 在文章JavaScript面向对象编程(一)原型与继承中讨论啦JavaScript中原型的概念,并且提到了new关键字和构造函数.利用new关键字构造对象的实例代码如下: // ...

  10. JavaScript 面向对象编程(三)如何写类和子类

    在JavaScript面向对象编程(一)原型与继承和JavaScript面向对象编程(二)构造函数和类中,我们分别讨论了JavaScript中面向对象的原型和类的概念.基于这两点理论,本篇文章用一个简 ...

随机推荐

  1. Bootstrap系列 -- 2. 标题

    一. Bootstrap标题 在Bootstrap中使用标题和Html本身没有太大的区别使用h1-h6, 而Bootstrap只是默认修改了H1-h6的样式,网上找到如下资料参考 二. Bootstr ...

  2. 2016 5.03开始记录我的it学习。

    好多谢立成师兄给我这个网址,我发现博客园不仅仅可以随笔记载很多东西,还是一个资源丰富的网站,接下来的四年我会用心去记录这些学习的点滴.

  3. input用法,永远等待,直到用户输入值赋值给一个东西。

    input用法,永远等待,直到用户输入值赋值给一个东西. n1 = input('请输入用户名:') n1 = input('请输入密码:') print(n1) print(n1)

  4. 深入 理解vxlan

    VXLAN RFC 文档 : https://tools.ietf.org/html/rfc7348 作为网络虚拟化的重要技术,VXLAN备受关注,该协议是如何运作的?如何通过数据与控制层面的分离实现 ...

  5. android 监听短信并发送到服务器

    1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. 2. 应用观察者模式,监听短信数据库,操作短信内容.   实例如下: SystemE ...

  6. Eclipse运行内存溢出

    VM arguments中添加如下: -Xms512m-Xmx1024m-XX:PermSize=256m-XX:MaxPermSize=256m-Xmn128m

  7. ubuntu下nginx的启停等常用命令

    开发过程中,我们会经常的修改nginx的配置文件,每次修改配置文件都可以先测试下本次修改的配置文件是否正确,可以利用以下命令: ? 1 service nginx -t -c /alidata/ser ...

  8. jQuery鼠标悬停内容动画切换效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 函数也是对象,本片介绍函数的属性、方法、Function()狗仔函数。

    1.arguments.length表示实参的个数. 2.arguments.callee.length表示形参个数. function test(a,b,c,d,e,f){ alert(argume ...

  10. 配置服务器有错/usr/libexec/gconf-sanity-check-2的退出状态为256

    问题描述: CentOS启动的时候报如下错误:“配置服务器有错/usr/libexec/gconf-sanity-check-2的退出状态为256” 问题原因: 在装hadoop的时候误删了/tmp文 ...