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学习实例7 Ajax所有过程事件分析示例
Mar 23 Javascript
简易js代码实现计算器操作
Apr 15 Javascript
JavaScript实现将xml转换成html table表格的方法
Apr 17 Javascript
Bootstrap树形控件使用方法详解
Jan 27 Javascript
JS功能代码集锦
May 04 Javascript
JS实现微信里判断页面是否被分享成功的方法
Jun 06 Javascript
详解关于react-redux中的connect用法介绍及原理解析
Sep 11 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
Feb 22 Javascript
谈谈JavaScript中super(props)的重要性
Feb 12 Javascript
了解JavaScript中let语句
May 30 Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
Jun 12 Javascript
基于layui实现高级搜索(筛选)功能
Jul 26 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的list()的一步操作给一组变量进行赋值的使用
2011/05/18 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
2011/11/27 PHP
简单的php新闻发布系统教程
2014/05/09 PHP
php session 写入数据库
2016/02/13 PHP
HR vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
用JavaScript对JSON进行模式匹配 (Part 2 - 实现)
2010/07/17 Javascript
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
学习JavaScript设计模式(策略模式)
2015/11/26 Javascript
浅析BootStrap栅格系统
2016/06/07 Javascript
JavaScript中输出信息的方法(信息确认框-提示输入框-文档流输出)
2016/06/12 Javascript
实例详解jQuery的无new构建
2016/08/02 Javascript
微信小程序使用第三方库Underscore.js步骤详解
2016/09/27 Javascript
javascript 中的继承实例详解
2017/05/05 Javascript
Angularjs 与 bower安装和使用详解
2017/05/11 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
Bootstrap 树控件使用经验分享(图文解说)
2017/11/06 Javascript
jQuery NProgress.js加载进度插件的简单使用方法
2018/01/31 jQuery
angular项目中bootstrap-datetimepicker时间插件的使用示例
2018/03/15 Javascript
JavaScript编码小技巧分享
2020/09/17 Javascript
vue浏览器返回监听的具体步骤
2021/02/03 Vue.js
python实现问号表达式(?)的方法
2013/11/27 Python
python获取文件后缀名及批量更新目录下文件后缀名的方法
2014/11/11 Python
python提取具有某种特定字符串的行数据方法
2018/12/11 Python
pyqt5 键盘监听按下enter 就登陆的实例
2019/06/25 Python
Python调用.NET库的方法步骤
2019/12/27 Python
Python爬取12306车次信息代码详解
2020/08/12 Python
python 偷懒技巧——使用 keyboard 录制键盘事件
2020/09/21 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
全球性的在线时尚男装零售商:boohooMAN
2016/12/17 全球购物
世界上最大的餐具公司:Oneida
2016/12/17 全球购物
英国综合网上购物商城:The Hut
2018/07/03 全球购物
2013年研究生毕业感言
2014/02/06 职场文书
学习两会精神心得范文
2014/03/17 职场文书
2014年信息技术工作总结
2014/12/16 职场文书
人事任命通知
2015/04/20 职场文书
MySQL令人咋舌的隐式转换
2021/04/05 MySQL