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 相关文章推荐
High Performance JavaScript(高性能JavaScript)读书笔记分析
May 05 Javascript
js切换div css注意的细节
Dec 10 Javascript
jquery click([data],fn)使用方法实例介绍
Jul 08 Javascript
js中function()使用方法
Dec 24 Javascript
教你如何使用PHP输出中文JSON字符串
May 22 Javascript
JavaScript使用function定义对象并调用的方法
Mar 23 Javascript
JavaScript实现信用卡校验方法
Apr 07 Javascript
JS实现横向拉伸动感伸缩菜单效果代码
Sep 04 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
Dec 05 Javascript
微信小程序swiper实现滑动放大缩小效果
Nov 15 Javascript
React中获取数据的3种方法及优缺点
Feb 18 Javascript
vue3不同环境下实现配置代理
May 25 Vue.js
剖析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截取字符串长度函数
2015/10/29 PHP
老生常谈PHP数组函数array_merge(必看篇)
2017/05/25 PHP
静态页面下用javascript操作ACCESS数据库(读增改删)的代码
2007/05/14 Javascript
利用cookie记住背景颜色示例代码
2013/11/04 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
利用进制转换压缩数字函数分享
2014/01/02 Javascript
Node.js 的异步 IO 性能探讨
2014/10/08 Javascript
编程语言JavaScript简介
2014/10/16 Javascript
JS+CSS实现仿触屏手机拨号盘界面及功能模拟完整实例
2015/05/16 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
2017/01/23 Javascript
vue-router:嵌套路由的使用方法
2017/02/21 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
vue使用mint-ui实现下拉刷新和无限滚动的示例代码
2017/11/06 Javascript
Vue中使用vue-i18插件实现多语言切换功能
2018/04/25 Javascript
小程序rich-text组件如何改变内部img图片样式的方法
2019/05/22 Javascript
微信小程序如何访问公众号文章
2019/07/08 Javascript
解决layui-table单元格设置为百分比在ie8下不能自适应的问题
2019/09/28 Javascript
[02:57]DOTA2亚洲邀请赛小组赛第四日 赛事回顾
2015/02/02 DOTA
[36:33]完美世界DOTA2联赛循环赛 Matador vs Forest 第一场 11.06
2020/11/06 DOTA
python+mysql实现简单的web程序
2014/09/11 Python
python在html中插入简单的代码并加上时间戳的方法
2018/10/16 Python
windows下搭建python scrapy爬虫框架步骤
2018/12/23 Python
Python使用grequests(gevent+requests)并发发送请求过程解析
2019/09/25 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
python自定义函数def的应用详解
2020/06/03 Python
Python使用OpenPyXL处理Excel表格
2020/07/02 Python
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
阿联酋手表和配饰购物网站:Rivolishop
2019/11/25 全球购物
酷瑞网络科技面试题
2012/03/30 面试题
校园达人秀策划书
2014/01/12 职场文书
诚信考试倡议书
2014/04/15 职场文书
2014年学校财务工作总结
2014/12/06 职场文书
先进党组织事迹材料
2014/12/26 职场文书
研讨会通知
2015/04/27 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python
图片批量处理 - 尺寸、格式、水印等
2022/03/07 杂记