Javascript中的Prototype到底是什么


Posted in Javascript onFebruary 16, 2016

Javascript也是面向对象的语言,但它是一种基于原型Prototype的语言,而不是基于类的语言。在Javascript中,类和对象看起来没有太多的区别。

什么是prototype:

function定义的对象有一个prototype属性,prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。 是不是很绕?用伪代码表示如下:

var function{
prototype:prototype{
constructor:constructor == function
}
}

还不明白?看图吧:

Javascript中的Prototype到底是什么

prototype的作用:

这个prototype到底有什么作用呢?看下面的例子:

function 3water(){
}
3water.prototype.name = "a";
var test = new 3water();
alert(test.name)//"a";

奇怪吧,明明没有为test设置name属性,可是为什么会有值?

这就是prototype的功劳了,uw3c中prototype属性中的name对象,在uw3c被new构造函数之后,被继承到了对象test的属性中。接着看:

var name = "js";
function 3water(name){
alert(this.name);//"css"
}
3water.prototype.name = "css";
var test = new 3water();
test()

为什么alert的值不是“js”?这个过程大致如下:

var test={};
uw3c.call(test);

第一步是建立一个新对象(test)。

第二步将该对象(test)内置的原型对象设置为构造函数(就是uw3c)prototype 属性引用的那个原型对象。

第三步就是将该对象(test)作为this 参数调用构造函数(就是uw3c),完成成员设置等初始化工作。

其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事, 为了区别我叫它inobj,inobj就指向了函数uw3c的prototype对象。在uw3c的prototype对象中出现的任何属性或者函数都可以在test对象中直接使用,这个就是JS中的原型继承了。

通常,这样创建一个对象:

function person(name){
this.sayHi = function(){
alert('hi ' + this.name);
}
this.name = name;
}
var p = new person("dan");
p.sayHi();

以上,使用new关键字,通过对象(函数也是特殊对象)创建一个对象实例。

在基于类的语言中,属性或字段通常都是在类中事先定义好了,但在Javascript中,在创建对象之后还可以为类添加字段。

function animal(){}
var cat = new animal();
cat.color = "green";

以上,color这个字段只属于当前的cat实例。
对于后加的字段,如果想让animal的所有实例都拥有呢?

--使用Prototype
function animal(){}
animal.prototype.color= "green";
var cat = new animal();
var dog = new animal();
console.log(cat.color);//green
console.log(dog.color);//green

通过Prototype不仅可以添加字段,还可以添加方法。

function animal(){}
animal.prototype.color= "green";
var cat = new animal();
var dog = new animal();
console.log(cat.color);//green
console.log(dog.color);//green
animal.prototype.run = funciton(){
console.log("run");
}
dog.run();

原来通过prototype属性,在创建对象之后还可以改变对象的行为。
比如,可以为数组这个特殊对象添加一个方法。

Array.prototype.remove = function(elem){
var index = this.indexof(elem);
if(index >= 0){
this.splice(index, 1);
}
}
var arr = [1, 2, 3] ;
arr.remove(2);

除了通过prototype为对象定义属性或方法,还可以通过对象的构造函数来定义类的属性或方法。

function animal(){
this.color = "green";
this.run = function(){
console.log("run");
}
}
var mouse = new animal();
mouse.run();

以上做法的也可以让所有的animal实例共享所有的字段和方法。并且还有一个好处是可以在构造函数中使用类的局部变量。

function animal(){
var runAlready = false;
this.color = "green";
this.run = funciton(){
if(!runAlreadh){
console.log("start running");
} else {
console.log("already running")
}
}
}

其实,一个更加实际的做法是把通过构造函数结合通过prototype定义一个类的字段和行为。

function animal(){
var runAlready = false;
this.run = function(){
if(!runAlready){
console.log('i am running');
} else {
console.log("i am already running");
}
}
}
animal.prototype.color = '';
animal.prototype.hide = funciton(){
console.log("");
}
var horse = new animal();
horse.run();
horse.hide();

Prototype允许我们在创建对象之后来改变对象或类的行为,并且这些通过prototype属性添加的字段或方法所有对象实例是共享的。

Javascript 相关文章推荐
用jquery统计子菜单的条数示例代码
Oct 18 Javascript
JavaScript实现多个重叠层点击切换效果的方法
Apr 24 Javascript
浅谈js中对象的使用
Aug 11 Javascript
用jquery获取自定义的标签属性的值简单实例
Sep 17 Javascript
js控制div层的叠加简单方法
Oct 15 Javascript
利用Bootstrap实现表格复选框checkbox全选
Dec 21 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
Mar 04 Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 Javascript
Vue中Axios从远程/后台读取数据
Jan 21 Javascript
Javascript数组方法reduce的妙用之处分享
Jun 10 Javascript
jQuery操作选中select下拉框的值代码实例
Feb 07 jQuery
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 Javascript
剖析Node.js异步编程中的回调与代码设计模式
Feb 16 #Javascript
使用Node.js处理前端代码文件的编码问题
Feb 16 #Javascript
让图片跳跃起来  javascript图片轮播特效
Feb 16 #Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
Feb 16 #Javascript
详解Node.js包的工程目录与NPM包管理器的使用
Feb 16 #Javascript
javascript每日必学之运算符
Feb 16 #Javascript
解析Node.js基于模块和包的代码部署方式
Feb 16 #Javascript
You might like
用来给图片加水印的PHP类
2008/04/09 PHP
深入php define()函数以及defined()函数的用法详解
2013/06/05 PHP
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
PHP内部实现打乱字符串顺序函数str_shuffle的方法
2019/02/14 PHP
jQuery 使用手册(七)
2009/09/23 Javascript
js 覆盖和重载 函数
2009/09/25 Javascript
js对象与打印对象分析比较
2013/04/23 Javascript
javascript函数声明和函数表达式区别分析
2014/12/02 Javascript
JS实现仿雅虎首页快捷登录入口及导航模块效果
2015/09/19 Javascript
深入理解JavaScript内置函数
2016/06/03 Javascript
jQuery操作iframe中js函数的方法小结
2016/07/06 Javascript
使用json来定义函数,在里面可以定义多个函数的实现方法
2016/10/28 Javascript
javascript设置文本框光标的方法实例小结
2016/11/04 Javascript
AngularJs 终极购物车(实例讲解)
2017/11/08 Javascript
微信小程序中吸底按钮适配iPhone X方案
2017/11/29 Javascript
详解jquery和vue对比
2019/04/16 jQuery
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
Vue双向数据绑定(MVVM)的原理
2020/10/03 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
2020/12/09 Javascript
[06:20]2015国际邀请赛第三日top10
2015/08/08 DOTA
使用Python实现简单的服务器功能
2017/08/25 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
python 消除 futureWarning问题的解决
2019/12/25 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
2020/02/03 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
Python sqlalchemy时间戳及密码管理实现代码详解
2020/08/01 Python
Python collections.deque双边队列原理详解
2020/10/05 Python
韩国休闲女装品牌网站:ANAIS
2016/08/24 全球购物
美国饼干礼物和美食甜点购买网站:Cheryl’s
2020/05/28 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
圆明园纪录片观后感
2015/06/03 职场文书
班主任工作经验交流会总结
2015/11/02 职场文书
2016大一新生入学教育心得体会
2016/01/23 职场文书
写好Python代码的几条重要技巧
2021/05/21 Python
go语言使用Casbin实现角色的权限控制
2021/06/26 Golang
dubbo服务整合zipkin详解
2021/07/26 Java/Android