JavaScript prototype对象的属性说明


Posted in Javascript onMarch 13, 2010

一、什么是JavaScript中对象的prototype属性

JavaScript中对象的prototype属性,是用来返回对象类型原型的引用的。我们使用prototype属性提供对象的类的一组基本功能。并且对象的新实例会”继承”赋予该对象原型的操作。但是这个prototype到底是怎么实现和被管理的呢?
对于对象的prototype属性的说明,JavaScript手册上如是说:所有 JavaScript内部对象都有只读的 prototype 属性。可以向其原型中动态添加功能(属性和方法),但该对象不能被赋予不同的原型。然而,用户定义的对象可以被赋给新的原型。

在JavaScript中,prototype对象是实现面向对象的一个重要机制。每个函数就是一个对象(Function),函数对象都有一个子对象prototype对象,类是以函数的形式来定义的。prototype表示该函数的原型,也表示一个类的成员的集合。在通过new创建一个类的实例对象的时候,prototype对象的成员都成为实例化对象的成员。

1、该对象被类所引用,只有函数对象才可引用;

2、在new实例化后,其成员被实例化,实例对象方可调用。

同时,函数是一个对象,函数对象若直接声明成员,不用被实例化即可调用。
JavaScript通过一种链接机制来支持继承,而不是通过完全面向对象语言(如Java)所支持的基于类的继承模型。每个JavaScript对象都有一个内置的属性,名为prototype。prototype属性保存着对另一个JavaScript对象的引用,这个对象作为当前对象的父对象。 
 

 当通过点记法引用对象的一个函数或属性时,倘若对象上没有这个函数或属性,此时就会使用对象的prototype属性。当出现这种情况时,将检查对象prototype属性所引用的对象,查看是否有所请求的属性或函数。如果prototype属性引用的对象也没有所需的函数或属性,则会进一步检查这个对象(prototype属性引用的对象)的prototype属性,依次沿着链向上查找,直到找到所请求的函数或属性,或者到达链尾,如果已经到达链尾还没有找到,则返回undefined。从这个意义上讲,这种继承结构更应是一种“has a”关系,而不是“is a”关系
神啊,我什么也看懂,怎么办?看似搞得我很牛,说实话我也看不懂!^_^ ^_^ ^_^
二、prototype属性应用实例
 我们所常见的类包括:数组变量(Array)、逻辑变量(Boolean)、日期变量(Date)、结构变量(Function)、数值变量(Number)、对象变量(Object)、字符串变量(String) 等,而相关的类的方法,也是程序员经常用到的(在这里要区分一下类的注意和属性发方法),例如数组的push方法、日期的get系列方法、字符串的split方法等等,

但是在实际的编程过程中不知道有没有感觉到现有方法的不足?prototype 方法应运而生!下面,将通过实例由浅入深讲解 prototype 的具体使用方法:
 先看一个很傻的例子:

JavaScript代码
function func(){   
    func.prototype.name = “prototype of func”;   
}   
var f = new func();          
alert(f.name);  //prototype of func
 先创建一个func对象,设置func对象的name属性,实例化f;

1.几个简单的例子:
(1)数字相加:
JavaScript代码
Number.prototype.add=function(num){   
    return (this+num);//这里的this指向Number   
};   
alert((3).add(15));//18  
(2) Boolean.rev(): 作用,布尔变量取反
实现方法:Boolean.prototype.rev = function(){return(!this);}
试验:alert((true).rev()) -> 显示 false
2、已有方法的实现和增强,初识 prototype:
(1) Array.push(new_element)

作用:在数组末尾加入一个新的元素

实现方法:

Array.prototype.push = function(new_element){
        this[this.length]=new_element;
        return this.length;
    }

让我们进一步来增强他,让他可以一次增加多个元素!

实现方法:

Array.prototype.pushPro = function() {
        var currentLength = this.length;
        for (var i = 0; i < arguments.length; i++) {
            this[currentLength + i] = arguments[i];
        }
        return this.length;
    }

应该不难看懂吧?以此类推,你可以考虑一下如何通过增强 Array.pop 来实现删除任意位置,任意多个元素(具体代码就不再细说了)

3、新功能的实现,深入 prototype:在实际编程中所用到的肯定不只是已有方法的增强,更多的实行的功能的要求,下面我就举两个用 prototype 解决实际问题的例子:
(1) String.left()

问题:用过 vb 的应该都知道left函数,从字符串左边取 n 个字符,但是不足是将全角、半角均视为是一个字符,造成在中英文混排的版面中不能截取等长的字符串

作用:从字符串左边截取 n 个字符,并支持全角半角字符的区分

实现方法:

String.prototype.left = function(num,mode){
        if(!/\d+/.test(num))return(this);
        var str = this.substr(0,num);
        if(!mode) return str;
        var n = str.Tlength() ? str.length;
        num = num ? parseInt(n/2);
        return this.substr(0,num);
    }

试验:alert(“aa啦啦aa”.left(4)) -> 显示 aa啦啦
     alert(“aa啦啦aa”.left(4,true)) -> 显示 aa啦

本方法用到了上面所提到的String.Tlength()方法,自定义方法之间也能组合出一些不错的新方法呀!
(2) Date.DayDiff()

作用:计算出两个日期型变量的间隔时间(年、月、日、周)

实现方法:

Date.prototype.DayDiff = function(cDate,mode){
        try{
            cDate.getYear();
        }catch(e){
            return(0);
        }
        var base =60*60*24*1000;
        var result = Math.abs(this ? cDate);
        switch(mode){
            case “y”:
                result/=base*365;
                break;
            case “m”:
                result/=base*365/12;
                break;
            case “w”:
                result/=base*7;
                break;
            default:
                result/=base;
                break;
        }
        return(Math.floor(result));
    }

试验:alert((new Date()).DayDiff((new Date(2002,0,1)))) -> 显示 329
     alert((new Date()).DayDiff((new Date(2002,0,1)),”m”)) -> 显示 10

当然,也可以进一步扩充,得出响应的小时、分钟,甚至是秒。
(3) Number.fact()

作用:某一数字的阶乘

实现方法:

Number.prototype.fact=function(){
        var num = Math.floor(this);
        if(num<0)return NaN;
        if(num==0 || num==1)
            return 1;
        else
            return (num*(num-1).fact());
    }

试验:alert((4).fact()) -> 显示 24

这个方法主要是说明了递归的方法在 prototype 方法中也是可行的!
 实例:
取数组的最大值:
JavaScript代码
var oArr=new Array();   
oArr=[100,190,199,189,3000,400,4001];   
Array.prototype.MAX=function(){   
    var i,max=this[0];   
    for(i=1;i<this.length;i++){   
        if(max<this[i]){   
            max=this[i];   
        }   
    }   
    return max;   
}   
alert(oArr.MAX());  
 实例为用户自定义类添加方法:
JavaScript代码
function TestObject()   
 {   
     this.m_Name = “ffffffffff”;   
 }   

 TestObject.prototype.ShowName = function()   
 {   
     alert(this.m_Name);   
 };   
var f=new TestObject();   
f.ShowName();  
更新自定义类的prototype:

JavaScript代码
function TestObjectA()   
{   
   this.MethodA = function()   
   {   
      alert(‘TestObjectA.MethodA()');   
   }   
}   

function TestObjectB()   
{   
   this.MethodB = function()   
   {   
      alert(‘TestObjectB.MethodB()');   
   }   
}   

TestObjectB.prototype = new TestObjectA();  
听说这是错说中的继承;哦以后慢慢学。
再看一个例子,估计你我都已经疯掉了:

JavaScript代码
function RP()   
{   
    RP.PropertyA = 1;   
    RP.MethodA = function()   
    {   
         alert(“RP.MethodA ”);   
    };   

    this.PropertyA = 100;    
    this.MethodA = function()   
    {   
         alert(“this.MethodA”);   
    };   
}   

RP.prototype.PropertyA = 10;    
RP.prototype.MethodA = function()   
{   
    alert(“RP.prototype.MethodA”);   
};   
//以下执行   
rp = new RP();   
alert(RP.PropertyA);//警告结果为:1   
RP.MethodA();//警告结果为:RP.MethodA   
alert(rp.PropertyA);//警告结果为:100   
rp.MethodA();//警告结果为:this.MethodA   
delete RP.PropertyA;   
alert(RP.PropertyA);//警告结果为:undefined   

delete rp.PropertyA;   
alert(rp.PropertyA);//警告结果为:100   
delete rp.MethodA;   
rp.MethodA();//警告结果为:RP.prototype.MethodA  
 再看一个带有参数的,计算圆的面积:

JavaScript代码
        <script type=“text/javascript”>   
function Circle(x,y,r){       
  this.x = x;       
  this.y = y;       
  this.r = r;       
  //this.prototype = null ;     /*这句代码可以看作是隐含存在的,因为javascript 中“类”的定义和函数的定义结构上没有差异,所以可以说,所有函数都隐藏有这样一个属性。*/       
}   
Circle.prototype.area=function(){   
    return this.r*this.r*3.1415926;   
}   
var Circ=new Circle(0,0,5);   
alert(parseInt(Circ.area()));   
        </script>  

Javascript 相关文章推荐
jquery获得option的值和对option进行操作
Dec 13 Javascript
fmt:formatDate的输出格式详解
Jan 09 Javascript
通过js来制作复选框的全选和不选效果
May 22 Javascript
javascript中CheckBox全选终极方案
May 20 Javascript
jQuery判断指定id的对象是否存在的方法
May 22 Javascript
JQuery入门基础小实例(1)
Sep 17 Javascript
js仿淘宝评价评分功能
Feb 28 Javascript
详解如何在你的Vue项目配置vux
Jun 04 Javascript
axios的拦截请求与响应方法
Aug 11 Javascript
新版小程序登录授权的方法
Dec 12 Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
Mar 12 #Javascript
JS在IE和FireFox之间常用函数的区别小结
Mar 12 #Javascript
javascript offsetX与layerX区别
Mar 12 #Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
Mar 12 #Javascript
javascript 图片上一张下一张链接效果代码
Mar 12 #Javascript
JQuery Ajax 跨域访问的解决方案
Mar 12 #Javascript
ExtJS 学习专题(一) 如何应用ExtJS(附实例)
Mar 11 #Javascript
You might like
Syphon 虹吸式咖啡壶冲煮–拨动法
2021/03/03 冲泡冲煮
PHP下通过系统信号量加锁方式获取递增序列ID
2009/09/25 PHP
PHP读取文件的常见几种方法
2016/11/03 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
laravel-admin的图片删除实例
2019/09/30 PHP
把html页面的部分内容保存成新的html文件的jquery代码
2009/11/12 Javascript
jQuery 动画弹出窗体支持多种展现方式
2010/04/29 Javascript
JavaScript实现的一个日期格式化函数分享
2014/12/06 Javascript
JavaScript基于setTimeout实现计数的方法
2015/05/08 Javascript
JavaScript中 ES6 generator数据类型详解
2016/08/11 Javascript
Node.JS利用PhantomJs抓取网页入门教程
2017/05/19 Javascript
jQuery Autocomplete简介_动力节点Java学院整理
2017/07/17 jQuery
Angularjs添加排序查询功能的实例代码
2017/10/24 Javascript
vue单页应用加百度统计代码(亲测有效)
2018/01/31 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
python2.7删除文件夹和删除文件代码实例
2013/12/18 Python
Python读取环境变量的方法和自定义类分享
2014/11/22 Python
详解Python中使用base64模块来处理base64编码的方法
2016/07/01 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
使用Python实现将list中的每一项的首字母大写
2019/06/11 Python
python 比较2张图片的相似度的方法示例
2019/12/18 Python
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
python生成任意频率正弦波方式
2020/02/25 Python
中国排名第一的外贸销售网站:LightInTheBox.com(兰亭集势)
2016/10/28 全球购物
纽约JewelryAffairs珠宝店:精细金银时尚首饰
2017/02/05 全球购物
Hotels.com韩国:海外国内旅行所需的酒店和住宿预订网站
2020/05/08 全球购物
《威尼斯的小艇》教学反思
2014/02/17 职场文书
行政内勤岗位职责
2014/04/07 职场文书
优秀团支部申报材料
2014/12/26 职场文书
中学生社区服务活动报告
2015/02/05 职场文书
导游词格式
2015/02/13 职场文书
介绍信怎么写
2015/05/05 职场文书
2015年民主评议党员工作总结
2015/05/19 职场文书
2016拓展训练心得体会范文
2016/01/12 职场文书
基于python制作简易版学生信息管理系统
2021/04/20 Python