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 更新 JavaScript 数组的 uniq 方法
Jan 23 Javascript
Js 获取Gridview选中行的内容操作步骤
Feb 05 Javascript
js日期相关函数总结分享
Oct 15 Javascript
angularJS中$apply()方法详解
Jan 07 Javascript
详解JavaScript数组的操作大全
Oct 19 Javascript
封装属于自己的JS组件
Jan 27 Javascript
BootStrap中Datepicker控件带中文的js文件
Aug 10 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
May 17 Javascript
addeventlistener监听scroll跟touch(实例讲解)
Aug 04 Javascript
在vue项目中使用Nprogress.js进度条的方法
Jan 31 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
Sep 02 Javascript
js+canvas实现转盘效果(两个版本)
Sep 13 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获取qq用户昵称和在线状态(实例分析)
2013/10/27 PHP
php检测用户是否用手机(Mobile)访问网站的类
2014/01/09 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
javascript的trim,ltrim,rtrim自定义函数
2008/09/21 Javascript
Firefox+FireBug使JQuery的学习更加轻松愉快
2010/01/01 Javascript
jQuery each()小议
2010/03/18 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
2012/01/15 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
2013/07/08 Javascript
用原生JS获取CLASS对象(很简单实用)
2014/10/15 Javascript
javascript表单事件处理方法详解
2016/05/15 Javascript
AngularJS  $modal弹出框实例代码
2016/08/24 Javascript
利用JQuery阻止事件冒泡
2016/12/01 Javascript
webpack入门必知必会
2017/01/16 Javascript
javascript过滤数组重复元素的实现方法
2017/05/03 Javascript
详解ES6中的三种异步解决方案
2018/06/28 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
在vue中实现禁止回退上一步,路由不存历史记录
2020/07/22 Javascript
Python抓取手机号归属地信息示例代码
2016/11/28 Python
python正则表达式爬取猫眼电影top100
2018/02/24 Python
使用python客户端访问impala的操作方式
2020/03/28 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
基于Python爬取搜狐证券股票过程解析
2020/11/18 Python
基于CSS3实现的几个小loading效果
2018/09/27 HTML / CSS
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
数据库的约束含义
2012/09/09 面试题
创伤外科专业推荐信范文
2013/11/19 职场文书
活动志愿者自荐信
2014/01/27 职场文书
招聘专员岗位职责
2014/03/07 职场文书
中国好声音广告词
2014/03/18 职场文书
师德师风建设整改措施思想汇报
2014/10/11 职场文书
预防艾滋病宣传活动总结
2015/05/09 职场文书
证婚人婚礼致辞
2015/07/28 职场文书
JavaScript 去重和重复次数统计
2021/03/31 Javascript