[js高手之路]使用原型对象(prototype)需要注意的地方
我们先来一个简单的构造函数+原型对象的小程序
function CreateObj( uName, uAge ) {
this.userName = uName;
this.userAge = uAge;
}
CreateObj.prototype.showUserName = function () {
return this.userName;
}
CreateObj.prototype.showUserAge = function () {
return this.userAge;
}
这个程序,没有什么问题,但是非常的冗余,每次扩展一个方法,都要写一次原型对象,我们可以把原型对象prototype当做一个字面量对象,所有的方法都在字面
量对象中扩展,可以达到同样的效果:
CreateObj.prototype = {
showUserAge : function(){
return this.userAge;
},
showUserName : function(){
return this.userName;
},
}
var obj1 = new CreateObj( 'ghostwu', 22 );
var obj2 = new CreateObj( '卫庄', 24 );
console.log( obj1.showUserName(), obj1.showUserAge() ); //ghostwu 22
console.log( obj2.showUserName(), obj2.showUserAge() ); //卫庄 24
但是这种原型(prototype)对象的写法,属于重写了CreateObj的默认原型对象,造成的第一个问题就是constructor不再指向CreateObj.
没有重写之前,constructor指向CreateObj
function CreateObj( uName, uAge ) {
this.userName = uName;
this.userAge = uAge;
}
CreateObj.prototype.showUserName = function () {
return this.userName;
}
CreateObj.prototype.showUserAge = function () {
return this.userAge;
}
console.log( CreateObj.prototype.constructor === CreateObj ); //true
重写之后,constructor指向Object
CreateObj.prototype = {
showUserAge : function(){
return this.userAge;
},
showUserName : function(){
return this.userName;
},
}
console.log( CreateObj.prototype.constructor === CreateObj ); //false
console.log( CreateObj.prototype.constructor === Object ); //true
所以说,constructor不能准确的标识对象,因为他会被修改
我们之前写的程序,基本都是在原型对象(prototype)上扩展完了方法之后,再实例化对象,我们看下,先实例化对象,再在原型对象(prototype)上扩展函数,
实例对象是否能正常的调用到扩展的方法?
function CreateObj( uName, uAge ) {
this.userName = uName;
this.userAge = uAge;
}
var obj1 = new CreateObj( 'ghostwu', 22 );
CreateObj.prototype.showUserName = function(){
return this.userName;
}
console.log( obj1.showUserName() ); //ghostwu
可以正常调用,但是,如果原型对象是重写的,就调用不到了
function CreateObj( uName, uAge ) {
this.userName = uName;
this.userAge = uAge;
}
var obj1 = new CreateObj( 'ghostwu', 22 );
CreateObj.prototype = {
showUserName : function(){
return this.userName;
}
}
console.log( obj1.showUserName() ); //报错
因为重写了原型对象之后,同时实例化又是在重写之前发生的,所以实例的隐式原型__proto__不会指向重写的原型对象,所以就调用不到
另一个问题,如果在原型对象(prototype)上有引用类型,千万小心,因为多个实例共用原型对象,只要有一个实例改变了引用类型的值,其他实例全部会收到
改变之后的结果。
function CreateObj(){}
CreateObj.prototype = {
name : 'ghostwu',
skills : [ 'php', 'javascript', 'linux' ]
};
var obj1 = new CreateObj();
obj1.skills.push( 'python' );
var obj2 = new CreateObj();
console.log( obj2.skills ); //'php', 'javascript', 'linux', 'python'
原型对象(prototype)的共享特性,可以很方便的为一些内置的对象扩展一些方法,比如,数组去重复
Array.prototype.unique = function(){
var res = [];
for( var i = 0, len = this.length; i < len; i++ ){
if( res.indexOf( this[i] ) == -1 ) {
res.push( this[i] );
}
}
return res;
}
var arr = [ 10, 20, 30, 20, 30, 20, 40, 20 ];
console.log( arr.unique() ); //10, 20, 30, 40
但是,不要随便往内置的对象上面扩展方法,在多人协作开发,很容易产生覆盖,以及污染.
[js高手之路]使用原型对象(prototype)需要注意的地方的更多相关文章
- [js高手之路]从原型链开始图解继承到组合继承的产生
基于javascript原型链的层层递进查找规则,以及原型对象(prototype)的共享特性,实现继承是非常简单的事情 一.把父类的实例对象赋给子类的原型对象(prototype),可以实现继承 f ...
- [js高手之路]原型对象(prototype)与原型链相关属性与方法详解
一,instanceof: instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型. 我在之前的两篇文章 [js高手之路]构造函数的基本特性与优缺点 [js高手 ...
- [js高手之路]一步步图解javascript的原型(prototype)对象,原型链
我们接着上文继续,我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉. function CreateObj(uName) { this ...
- [js高手之路] es6系列教程 - 对象功能扩展详解
第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...
- js高级——构造函数,实例对象和原型对象——prototype、__proto__和constructor构造器
一.前言 了解JavaScript面向对象,需要先了解三个名词: 构造函数,实例对象和原型对象. 注意:JavaScript中没有类(class)的概念,取而代之的是构造函数,两者类似却又有很大的差别 ...
- [js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表
所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理, ...
- [js高手之路] 设计模式系列课程 - jQuery的extend插件机制
这里在之前的文章[js高手之路] 设计模式系列课程 - jQuery的链式调用与灵活的构造函数基础上增加一个extend浅拷贝,可以为对象方便的扩展属性和方法, jquery的插件扩展机制,大致就是这 ...
- [js高手之路] es6系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解
接着上文[js高手之路] es6系列教程 - 迭代器与生成器详解继续. 在es6中引入了一个新的循环结构for ....of, 主要是用来循环可迭代的对象,那么什么是可迭代的对象呢? 可迭代的对象一般 ...
- [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)
关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...
随机推荐
- ps_cc切片
web前端开发的工作流程的第一步就是根据ui给的psd来还原设计图样貌. 可是一打开满屏的参考线.这时我们可以alt+v+d清空参考线 这时可以按alt+鼠标拖放图片.同时也可以按F进入半屏和匀速连按 ...
- ChartCtrl源码剖析之——CChartObject类
首先,做一些简单的铺垫,目前针对ChartCtrl源码的剖析只针对V.15版本.名义上说是剖析,倒不如说是记录下自己针对该控件的理解,非常感谢Cedric Moonen大神,一切的功劳与掌声都该赠予给 ...
- JS - 数据类型的值拷贝函数(深拷贝)
function mottoClone (obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanc ...
- Pivot Table系列之切片器 (Slicer)
1. 遇到的问题: 在Excel中,用PivotTable来做数据报告展示: 问题1:在同一个Sheet页里,多个PivotTable如何实现同步刷新? 问题2:在不同Sheet页之间,多个Pivot ...
- Hybris安装和各个Extention简单介绍
前言:突然想好好梳理一下这几个月所学的内容了,顺便让自己的知识有一个系统的框架. 一. 安装JDK 请安装最新的Oracle JDK 8.0版(从Oracle官网下载). 二.开发工具建议使用 In ...
- linux kill杀死进程
背景:这个命令总是记不住,在此稍作记录,方便查看! 1 杀死进程 1.1 查看进程 此时如果我想杀了火狐的进程就在终端输入: $ kill -s 9 1827 其中-s 9 制定了传递给进程的信号是9 ...
- API和schema开发过程问题汇总
场景:在日常工作中很多都是重复性的劳动,有的坑踩过一次下次很可能还回踩到,所以很有必要将这些问题记录下来,提升工作效率! 1 API 2 schema 问题:提示schame中有元素没有定义 这个时候 ...
- div+css命名规范大全
网页制作中规范使用DIV+CSS命名规则,可以改善优化功效特别是团队合作时候可以提供合作制作效率, 我们开发DIV+CSS网页(Xhtml)时候,比较困惑和纠结的事就是CSS命名,特别是新手不知道什么 ...
- GateSvr的设计2
我们的目标是:1.业务Server集群部署,从网关发来的请求处理,程序自动找一台空闲的业务Server来处理这个请求,并将结果异步分发到服务网关,从而Push给客户端:2.一套业务Server挂了不会 ...
- 《深入理解Java虚拟机》虚拟机类加载机制
上节学习回顾 上一节,我们深入到类文件去了解其结构细节,也大概对类文件的编写规则略知一二了,解析来我们就得学习这个类文件是如何被加载到Java虚拟机的,看看有什么引人入胜的奥秘. 本节学习重点 大部分 ...