零.此文动机

  用了一段时间的Lua,用惯了Java C++等有Class关键字的语言,一直对Lua的中的面向对象技术感到费解,一个开源的objectlua更是看了n遍也没理解其中的原理,直到看到了Prototype-based programming

一.什么是基于原型的编程

  基于原型的编程是面向对象编程的一种形式,通过复制已经存在的原型对象来实现面向对象,无与基于类的编程较大的区别是没有Class关键字,但是有类的概念。基于原型的编程也可以理解成基于实例的编程。

  基于原型的系统可以在程序运行时对原型进行修改,基于类(Java, C+)的语言则很难实现这一点。这么说比较抽象,下面会对比基于原型的类(JavaScript)和基于类的编程区别。

二.JavaScript中的类继承

  一.java中的类

   java实现类有现成的关键字class,用java实现一个动物类,并实现一个人类来继承动物类。

 class Animal {
public Animal() {
name = "Animal";
}
public String eat() {
return "eat!";
}
public String name;
} class People extends Animal {
public People() {
super();
name = "people";
}
}

  二.JavaScript中的类

  JavaScript定义了少数的数据类型:null,undefined,Boolean,Number,Function,Object(对象)。每个对象都有类属性,但是不能通过.class来访问,只能通过.toString方法来访问。但是很多对象继承的toString()方法重写了,所以要调用Function.call()方法。

 object.prototype.toString.call("")
//[object String]
object.prototype.toString.call(1)
//[object Number]
object.prototype.toString.call([])
//[object Array]
function f(){}
object.prototype.toString.call(new f())
//[object Object]

  每个对象除了有类属性外,还有原型属性(__proto__),这个属性便是用来继承的,对对象属性的查询,若没有此属性,便到其原型中继续查找。比如有对象A和对象B,A.__proto__ = B,执行代码A.b,若A.b == null, 再查找B.b,若找到则作为A.b的返回,若没有找到则继续到B的原型中找,直到找到或原型(Ojbect.prototype.__proto__)为空。JavaScript中的面向对象需要写一整篇博文来捋顺,下面只写最基本的对象继承。同样是上面人继承动物的例子,JavaScript这么搞:

 var Animal = {
name : "Animal",
eat : function() {
return "eat!"
}
}; var People = {
name : "People"
} People.__proto__ = Animal; People.eat()
// "eat!"
People.name
// "People"

  People.__proto__ = Animal,便是让People的原型为Animal,实现People对Animal的继承,People.eat()返回“eat!”.

  这种原型的继承有什么优点呢?我理解到的是可以进行运行中的类修改,比如下面的代码,程序运行中在想在基类中添加属性或方法,java就不能做到。

 //继续上面代码
Animal.run = function () {
return "Animal run";
}
People.run()
// "Animal run"

三.其他基于原型的语言

  C++中的类只是对象的布局的定义,其肯定不是基于原型的语言。

  那Java呢,Java中的类也是对象,那Java是不是基于原型的语言呢?不是!简单的判断Java提供了Class关键字……更关键的是Java是一种强类型语言,所以其不具有动态扩展性。

  个人觉得记忆原型的语言必须具备下面2个特点:

  • 弱类型
  • 动态可扩展  

  具备这两个特点的语言看着那么像脚本语言呢,是的,Lua,Tcl,Perl【1】都是基于对象的语言。Python比较特殊,其语言级别提供了Class关键字,但是它又满足弱类型与动态可扩展,这时就不要纠结它是不是面向原型的语言了,个人愿意认为它是基于类的语言,毕竟提供了Class关键字…… 这个貌似是让python看起来像是基于原型语言的东东。

参考

  1. https://en.wikipedia.org/wiki/Prototype-based_programming
  2. http://www.cnblogs.com/winter-cn/archive/2008/06/02/1212167.html
  3. JavaScript权威指南第六版

通过JavaScript原型链理解基于原型的编程的更多相关文章

  1. js原型链理解(2)--原型链继承

    1.原型链继承 2.constructor stealing(构造借用) 3.组合继承 js中的原型链继承,运用的js原型链中的__proto__. function Super(){ this.se ...

  2. 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统

    面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...

  3. JavaScript ES5类 原型 原型链 组合、原型、寄生式继承

    ES5类 原型  原型链 继承 JavaScript中,原型是相对于构造函数(类)的叫法(或者说概念),原型链是相对于构造函数(类)的实例对象的叫法. 对于JavaScript对象,如果在对象自身上找 ...

  4. 前端知识体系:JavaScript基础-原型和原型链-理解 es6 中class构造以及继承的底层实现原理

    理解 es6 中class构造以及继承的底层实现原理 原文链接:https://blog.csdn.net/qq_34149805/article/details/86105123 1.ES6 cla ...

  5. 前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则

    理解原型设计模式以及 JavaScript中的原型规则(原文地址) 1.原型对象:我们创建的每一个函数(JavaScript中函数也是一个对象)都有一个原型属性 prototype,原型属性实质上是一 ...

  6. js原型和原型链理解到面向对象

    一.js中的两种对象,普通对象和函数对象 var obj1 = {}; var obj2 =new Object(); var obj3 = new obj1(); function fun1(){} ...

  7. js原型链理解(3)--构造借用继承

    构造借用(constructor strealing) 1.为什么已经存在原型链继承还要去使用构造借用 首先看一下这个例子 function Super(){ this.sets = [0,1,2]; ...

  8. JS原型链理解

    1. 每个对象都有原型属性(__proto__)2. 对象的原型(__proto__)指向其构造函数(Class)的prototype属性3. 构造函数(Class)的prototype属性本身也是一 ...

  9. js原型链理解(4)-经典继承

    经典继承就是组合继承,就是组合构造函数和原型链的优点混合继承. 1.避免引用类型的属性初始化 2.避免相同方法的多次初始化 function Super(name){ this.ages = [100 ...

随机推荐

  1. 大数据下的Distinct Count(一):序

    在数据库中,常常会有Distinct Count的操作,比如,查看每一选修课程的人数: select course, count(distinct sid) from stu_table group ...

  2. SQL Server代理(1/12):配置和概况

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. SQL Server代理是SQL Serv ...

  3. SQL Server时间粒度系列----第3节旬、月时间粒度详解

    本文目录列表: 1.SQL Server旬时间粒度2.SQL Server月有关时间粒度 3.SQL Server函数重构 4.总结语 5.参考清单列表   SQL Server旬时间粒度       ...

  4. Lambda表达式演变

    Lambda表达式是一种匿名函数.   演变步骤:   一般的方法委托 => 匿名函数委托 => Lambda表达式   Lambda表达式其实并不陌生,他的前生就是匿名函数,所以要谈La ...

  5. 【转载】8天学通MongoDB——第四天 索引操作

    这些天项目改版,时间比较紧,博客也就没跟得上,还望大家见谅. 好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们 又 ...

  6. 参数类型params

    params参数练习 namespace Test { class Program { static void Main(string[] args) { //params 构造函数声明数组,可变数组 ...

  7. asp.net各种cookie代码和解析

    Cookie是一段文本信息,在客户端存储 Cookie 是 ASP.NET 的会话状态将请求与会话关联的方法之一.Cookie 也可以直接用于在请求之间保持数据,但数据随后将存储在客户端并随每个请求一 ...

  8. Malformed \uxxxx encoding解决方法

    java.lang.IllegalArgumentException: Malformed \uxxxx encoding. at java.util.Properties.loadConvert(U ...

  9. PHP组件化开发

    设计思想中有两种极端:大而全.小而美. 一般我们常用的库是小而美,用的框架是大而全.从Symfony实现Component式开发开始,框架的组件化逐渐成为趋势.我们可以任意的组合各种Compoent来 ...

  10. oracle sql初次接触

    oracle 语法有些地方都是和mysql一样,但还是有很多不同之处: 注意:dual该表为oracle中本身就存在的数据表.比如想取数据库时间(系统时间)就可以用这张表来完成. 创建表语法: cre ...