通过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 ...
随机推荐
- 基于HTML5 Canvas实现工控2D叶轮旋转
之前在拓扑上的应用都是些静态的图元,今天我们将在拓扑上设计一个会动的图元——叶轮旋转. http://www.hightopo.com/guide/guide/core/serialization/e ...
- Spring MVC 对于@ModelAttribute 、@SessionAttributes 的详细处理流程
初学 Spring MVC , 感觉对于 @ModelAttribute 和 @SessionAttributes 是如何被Spring MVC处理的,这一流程不是很清楚, 经过Google资料,有了 ...
- 【转】MyEclipse 2015优化技巧
MyEclipse 2015优化技巧 MyEclipse 2015优化速度方案仍然主要有这么几个方面:去除无需加载的模块.取消冗余的配置.去除不必要的检查.关闭更新. 第一步: 去除不需要加载的模块 ...
- 更新整理本人所有博文中提供的代码与工具(C++,2013.10)
为了更方便地管理博文中涉及的各种代码与工具资源,现在把这些资源迁移到 Google Code 中,有兴趣者可前往下载. C++ 1.<通用高性能 Windows Socket 组件 HP-Soc ...
- Release编译模式下,事件是否会引起内存泄漏问题初步研究
题记:不常发生的事件内存泄漏现象 想必有些朋友也常常使用事件,但是很少解除事件挂钩,程序也没有听说过内存泄漏之类的问题.幸运的是,在某些情况下,的确不会出问题,很多年前做的项目就跑得好好的,包括我也是 ...
- linux常用命令之文件权限
CHGRP chgrp – change group ownership,改变组别的所有权 用法 chgrp 组别名 文件\目录名 选项 -R (recursive)递归改变,将目录下所有的文件和目 ...
- ArcGIS Server 开发之鹰眼地图的实现
鹰眼简单点说就是地图的联动,鹰眼的全称是OverviewMap,在ERSI提供的API包中,在dijit中进行类的调用.查了很多的资料,总结一下: 具体的代码: <!DOCTYPE html&g ...
- fakeLoader页面加载前loading演示8种效果
提高用户体验的插件fakeLoader页面加载前loading演示8种效果 在线预览 下载地址 示例代码 <div id="main"> <div class=& ...
- Dynamics.js - 创建逼真的物理动画的 JS 库
Dynamics.js 是一个用来创建物理动画 JavaScript 库.你只需要把dynamics.js引入你的页面,然后就可以激活任何 DOM 元素的 CSS 属性动画,也可以用户 SVG 属性. ...
- 【HTML5】浅析HTML5应用程序缓存(ApplicationCache)
一.为什么需要Web应用程序缓存 在移动互联网时代,设备终端位置不再固定,依赖无线信号,网络的可靠性变得降低,比如坐在火车上,过了一个隧道(15分钟),便无法访问网站,这对于web的伤害是很大的 ...