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 相关文章推荐
JS 自动安装exe程序
Nov 30 Javascript
使用JavaScript库还是自己写代码?
Jan 28 Javascript
判断客户端浏览器是否安装了Flash插件的多种方法
Aug 11 Javascript
js操作css属性实现div层展开关闭效果的方法
May 11 Javascript
JavaScript的Date()方法使用详解
Jun 09 Javascript
Jquery实现顶部弹出框特效
Aug 08 Javascript
javascript中利用柯里化函数实现bind方法
Apr 29 Javascript
JS判断字符串变量是否含有某个字串的实现方法
Jun 03 Javascript
JQuery对ASP.NET MVC数据进行更新删除
Jul 13 Javascript
详解js中Array的方法及技巧
Sep 12 Javascript
vue最简单的前后端交互示例详解
Oct 11 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
Sep 06 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
动漫女神老婆无限好,但日本女生可能就不是这么一回事了!
2020/03/04 日漫
一个用php3编写的简单计数器
2006/10/09 PHP
php的大小写敏感问题整理
2011/12/29 PHP
利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
2017/06/27 PHP
解决jquery的datepicker的本地化以及Today问题
2012/05/23 Javascript
原生js实现跨浏览器获取鼠标按键的值
2013/04/08 Javascript
jquery中文乱码的多种解决方法
2013/06/21 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
js弹出框、对话框、提示框、弹窗实现方法总结(推荐)
2016/05/31 Javascript
AngularJS入门教程之过滤器用法示例
2016/11/02 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
浅谈React 属性和状态的一些总结
2016/11/21 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
2017/01/21 Javascript
微信小程序开发之toast等弹框提示使用教程
2017/06/08 Javascript
JavaScript面向对象程序设计创建对象的方法分析
2018/08/13 Javascript
Javascript confirm多种使用方法解析
2020/09/25 Javascript
Django 实现下载文件功能的示例
2018/03/06 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
python实现动态创建类的方法分析
2019/06/25 Python
Python目录和文件处理总结详解
2019/09/02 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
python中逻辑与或(and、or)和按位与或异或(&、|、^)区别
2020/08/05 Python
Python实现EM算法实例代码
2020/10/04 Python
ProBikeKit德国:在线公路自行车专家
2018/06/03 全球购物
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
eBay爱尔兰站:eBay.ie
2019/08/09 全球购物
新领导上任欢迎词
2014/01/13 职场文书
模范家庭事迹材料
2014/02/10 职场文书
校园学雷锋活动月总结
2014/03/09 职场文书
媒体宣传策划方案
2014/05/25 职场文书
县委常委班子专题民主生活会查摆问题及整改措施
2014/09/27 职场文书
三八妇女节标语
2014/10/09 职场文书
山东省召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
财务经理岗位职责
2015/01/31 职场文书
2015年健康教育工作总结
2015/04/10 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书