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转换字符串为dom对象(字符串动态创建dom)
May 10 Javascript
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
May 24 Javascript
JS实现黑色大气的二级导航菜单效果
Sep 18 Javascript
谈谈JavaScript类型系统之Math
Jan 06 Javascript
基于BootStrap栅格栏系统完成网站底部版权信息区
Dec 23 Javascript
vue路由组件按需加载的几种方法小结
Jul 12 Javascript
简述vue状态管理模式之vuex
Aug 29 Javascript
Vue Cli3 创建项目的方法步骤
Oct 15 Javascript
vue ssr 实现方式(学习笔记)
Jan 18 Javascript
vue 地图可视化 maptalks 篇实例代码详解
May 21 Javascript
Element DateTimePicker日期时间选择器的使用示例
Jul 27 Javascript
微信小程序实现modal弹出框遮罩层组件(可带文本框)
Dec 20 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教程之PHP中shell脚本的使用方法分享
2012/02/23 PHP
PHP大小写问题:函数名和类名不区分,变量名区分
2013/06/17 PHP
优化WordPress中文章与评论的时间显示
2016/01/12 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
2019/03/18 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
Jquery实战_读书笔记1—选择jQuery
2010/01/22 Javascript
js RuntimeObject() 获取ie里面自定义函数或者属性的集合
2010/11/23 Javascript
JQuery中extend使用介绍
2014/03/13 Javascript
七个不允许错过的jQuery小技巧
2015/12/21 Javascript
jquery基础知识第一讲之认识jquery
2016/03/17 Javascript
js css+html实现简单的日历
2016/07/14 Javascript
js 声明数组和向数组中添加对象变量的简单实例
2016/07/28 Javascript
vue-cli 3.x 修改dist路径的方法
2018/09/19 Javascript
点击按钮弹出模态框的一系列操作代码实例
2019/03/29 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
Python中if __name__ == "__main__"详细解释
2014/10/21 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
Python的requests网络编程包使用教程
2016/07/11 Python
用pandas中的DataFrame时选取行或列的方法
2018/07/11 Python
Python实现的json文件读取及中文乱码显示问题解决方法
2018/08/06 Python
Python获取数据库数据并保存在excel表格中的方法
2019/06/12 Python
浅析pandas 数据结构中的DataFrame
2019/10/12 Python
基于python中__add__函数的用法
2019/11/25 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
Django 权限管理(permissions)与用户组(group)详解
2020/11/30 Python
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
意大利咖啡、浓缩咖啡和浓缩咖啡机:illy caffe
2019/03/20 全球购物
软件工程专业推荐信
2013/10/28 职场文书
车工岗位职责
2013/11/26 职场文书
小学生打架检讨书
2014/01/26 职场文书
中学自我评价
2014/01/31 职场文书
医学生个人求职信范文
2014/02/07 职场文书
青春无悔演讲稿
2014/05/08 职场文书
清明祭英烈活动总结
2015/05/11 职场文书
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang