通过JavaScript原型链理解基于原型的编程
零.此文动机
用了一段时间的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看起来像是基于原型语言的东东。
参考
- https://en.wikipedia.org/wiki/Prototype-based_programming
- http://www.cnblogs.com/winter-cn/archive/2008/06/02/1212167.html
- JavaScript权威指南第六版
通过JavaScript原型链理解基于原型的编程的更多相关文章
- js原型链理解(2)--原型链继承
1.原型链继承 2.constructor stealing(构造借用) 3.组合继承 js中的原型链继承,运用的js原型链中的__proto__. function Super(){ this.se ...
- 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统
面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...
- JavaScript ES5类 原型 原型链 组合、原型、寄生式继承
ES5类 原型 原型链 继承 JavaScript中,原型是相对于构造函数(类)的叫法(或者说概念),原型链是相对于构造函数(类)的实例对象的叫法. 对于JavaScript对象,如果在对象自身上找 ...
- 前端知识体系:JavaScript基础-原型和原型链-理解 es6 中class构造以及继承的底层实现原理
理解 es6 中class构造以及继承的底层实现原理 原文链接:https://blog.csdn.net/qq_34149805/article/details/86105123 1.ES6 cla ...
- 前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则
理解原型设计模式以及 JavaScript中的原型规则(原文地址) 1.原型对象:我们创建的每一个函数(JavaScript中函数也是一个对象)都有一个原型属性 prototype,原型属性实质上是一 ...
- js原型和原型链理解到面向对象
一.js中的两种对象,普通对象和函数对象 var obj1 = {}; var obj2 =new Object(); var obj3 = new obj1(); function fun1(){} ...
- js原型链理解(3)--构造借用继承
构造借用(constructor strealing) 1.为什么已经存在原型链继承还要去使用构造借用 首先看一下这个例子 function Super(){ this.sets = [0,1,2]; ...
- JS原型链理解
1. 每个对象都有原型属性(__proto__)2. 对象的原型(__proto__)指向其构造函数(Class)的prototype属性3. 构造函数(Class)的prototype属性本身也是一 ...
- js原型链理解(4)-经典继承
经典继承就是组合继承,就是组合构造函数和原型链的优点混合继承. 1.避免引用类型的属性初始化 2.避免相同方法的多次初始化 function Super(name){ this.ages = [100 ...
随机推荐
- Elasticsearch增删改查 之 —— Get查询
GET API是Elasticsearch中常用的操作,一般用于验证文档是否存在:或者执行CURD中的文档查询.与检索不同的是,GET查询是实时查询,可以实时查询到索引结果.而检索则是需要经过处理,一 ...
- web框架--bottle
安装 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.o ...
- Block的用法
定义block 无参数无返回值的block 定义格式: void (^block)() = ^{ NSLog(@"block"); }; 有参有返回值的block 定义格式 int ...
- 【Swift学习】Swift编程之旅(一)
学习一门新语言最经典的例子就是输出“Hello World!” print("Hello World!") swift就是这样来输出的. 如果你使用过其他语言,那么看上去是非常的熟 ...
- ASP.NET MVC 使用Jquery Uploadify 在非IE浏览器下Http Error的解决方案
解决Uploadify上传控件在非IE浏览器中不工作,需要做如下2步修改: 1.Global.asax文件中,实现Application_BeginRequest函数: void Applicatio ...
- 目标平台、活动平台 配置,出现未能加载文件或程序集“xxx”或它的某一个依赖项报错
今天在做动态加载程序集的时候,发现明明程序集存在的情况下,还是依然报“未能加载文件或程序集“xxx”或它的某一个依赖项报错”的错误,排除了程序和配置的错误后,怀疑是否是环境的问题,于是百度加msdn后 ...
- Wojilu学习笔记 (01)
“我记录”开发框架(wojilu framework) 是 .net 平台下的综合开发框架,主要用于 web 方面的快速开发. 官方网址:http://www.wojilu.com源码托管网址: ht ...
- springmvc restful配置有一个小小的坑坑
首先web.xml配置 <!-- spring-mvc --> <servlet> <servlet-name>springServlet</servlet- ...
- mysql易混淆知识点
1,join 和 union join连接属于表之间的水平操作,而union 是表之间的垂直操作.简单讲就是水平操作主要是为了获得列数据,垂直操作是为了获得行数据 cross join ...
- PHP内核探索之变量(6)- 后续内核探索系列大纲备忘
年前因为工作比较饱和,现在又忙着换工作的事情,基本停止了对博文的更新.后续的博文,还是慢慢补上吧. 为了不至于过于发散,先搞个未成形的大纲,如下: PHP内核探索之变量 不平凡的字符串 PHP内核探 ...