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 相关文章推荐
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
Feb 27 Javascript
Jquery:ajax实现翻页无刷新功能代码
Aug 05 Javascript
JQUERY 设置SELECT选中项代码
Feb 07 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
Mar 04 Javascript
js 创建对象 经典模式全面了解
Aug 16 Javascript
微信小程序开发一键登录 获取session_key和openid实例
Nov 23 Javascript
jQuery获取this当前对象子元素对象的方法
Nov 29 Javascript
JavaScript Base64 作为文件上传的实例代码解析
Feb 14 Javascript
Vue键盘事件用法总结
Apr 18 Javascript
解决Vue打包之后文件路径出错的问题
Mar 06 Javascript
vue 实现 rem 布局或vw 布局的方法
Nov 13 Javascript
Node.js API详解之 readline模块用法详解
May 22 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
Terran建筑一览
2020/03/14 星际争霸
十天学会php之第八天
2006/10/09 PHP
PHP中调用ASP.NET的WebService的代码
2011/04/22 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
PHP面向对象之后期静态绑定功能介绍
2015/05/18 PHP
php获取文章内容第一张图片的方法示例
2017/07/03 PHP
Yii2框架可逆加密简单实现方法
2017/08/25 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
你可能不知道的JavaScript的new Function()方法
2014/04/17 Javascript
js重写alert控件(适合学习js的新手朋友)
2014/08/24 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
2015/05/28 Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
2016/02/27 Javascript
JavaScript基础重点(必看)
2016/07/09 Javascript
vue-lazyload图片延迟加载插件的实例讲解
2018/02/09 Javascript
基于cropper.js封装vue实现在线图片裁剪组件功能
2018/03/01 Javascript
webpack4.x打包过程详解
2018/07/18 Javascript
tsconfig.json配置详解
2019/05/17 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
2019/06/03 Javascript
vue实现前端列表多条件筛选
2020/10/26 Javascript
[01:00:22]DOTA2-DPC中国联赛定级赛 LBZS vs Magma BO3第三场 1月10日
2021/03/11 DOTA
Python argv用法详解
2016/01/08 Python
Python打包可执行文件的方法详解
2016/09/19 Python
Python实现模拟分割大文件及多线程处理的方法
2017/10/10 Python
python matplotlib 注释文本箭头简单代码示例
2018/01/08 Python
FFT快速傅里叶变换的python实现过程解析
2019/10/21 Python
在 Jupyter 中重新导入特定的 Python 文件(场景分析)
2019/10/27 Python
Mybag美国/加拿大:英国奢华包包和名牌手袋网站
2020/02/16 全球购物
计算机专业毕业生的自我评价
2013/11/18 职场文书
行政办公员自我评价分享
2013/12/14 职场文书
铁路安全事故反思
2014/04/26 职场文书
党的群众路线教育实践活动查摆剖析材料
2014/10/10 职场文书
违反交通安全法检讨书
2014/10/24 职场文书
民事代理词范文
2015/05/25 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL