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怎样实现ajax联动框(一)
Mar 08 Javascript
『jQuery』名称冲突使用noConflict方法解决
Apr 22 Javascript
JS+DIV实现鼠标划过切换层效果的实例代码
Nov 26 Javascript
jquery控制背景音乐开关与自动播放提示音的方法
Feb 06 Javascript
js调用百度地图及调用百度地图的搜索功能
Sep 07 Javascript
js实现页面a向页面b传参的方法
May 29 Javascript
js实现碰撞检测特效代码分享
Oct 16 Javascript
JavaScript输入框字数实时统计更新
Jun 17 Javascript
深入理解es6块级作用域的使用
Mar 28 Javascript
ECharts地图绘制和钻取简易接口详解
Jul 12 Javascript
微信小程序实现定位及到指定位置导航的示例代码
Aug 20 Javascript
整理 node-sass 安装失败的原因及解决办法(小结)
Feb 19 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
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
PHP实现的文件操作类及文件下载功能示例
2016/12/24 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
PHP实现长轮询消息实时推送功能代码实例讲解
2021/02/26 PHP
用tip解决Ext列宽度不够的问题
2008/12/13 Javascript
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
JS获取html对象的几种方式介绍
2013/12/05 Javascript
javascript中全局对象的isNaN()方法使用介绍
2013/12/19 Javascript
javascript对象的使用和属性操作示例详解
2014/03/02 Javascript
如何获取网站icon有哪些可行的方法
2014/06/05 Javascript
js实现按钮加背景图片常用方法
2014/11/01 Javascript
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
easyui-datagrid特殊字符不能显示的处理方法
2017/04/12 Javascript
ES6中javascript实现函数绑定及类的事件绑定功能详解
2017/11/08 Javascript
基于express中路由规则及获取请求参数的方法
2018/03/12 Javascript
详解webpack loader和plugin编写
2018/10/12 Javascript
postman自定义函数实现 时间函数的思路详解
2019/04/17 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
Python continue语句用法实例
2014/03/11 Python
python绘制铅球的运行轨迹代码分享
2017/11/14 Python
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
对python中执行DOS命令的3种方法总结
2018/05/12 Python
Python设计模式之策略模式实例详解
2019/01/21 Python
python如何实现异步调用函数执行
2019/07/08 Python
教你如何编写、保存与运行Python程序的方法
2019/07/12 Python
Python 字符串、列表、元组的截取与切片操作示例
2019/09/17 Python
Casetify官网:自制专属手机壳、iPad护壳和Apple Watch手表带
2018/05/09 全球购物
彪马日本官网:PUMA日本
2019/01/31 全球购物
介绍一下RMI的基本概念
2016/12/17 面试题
会计自荐书
2013/12/02 职场文书
前台文员个人求职信范文
2014/01/05 职场文书
教师业务培训方案
2014/05/01 职场文书
会议简报格式范文
2015/07/20 职场文书
2016高考寄语或鼓励的话语
2015/12/04 职场文书