资讯专栏INFORMATION COLUMN

[js高手之路]使用原型对象(prototype)需要注意的地方

chnmagnus / 2469人阅读

摘要:原型对象的共享特性,可以很方便的为一些内置的对象扩展一些方法,比如,数组去重复但是,不要随便往内置的对象上面扩展方法,在多人协作开发,很容易产生覆盖,以及污染

我们先来一个简单的构造函数+原型对象的小程序

 1         function CreateObj( uName, uAge ) {
 2             this.userName = uName;
 3             this.userAge = uAge;
 4         }
 5         CreateObj.prototype.showUserName = function () {
 6             return this.userName;
 7         }
 8         CreateObj.prototype.showUserAge = function () {
 9             return this.userAge;
10         }

这个程序,没有什么问题,但是非常的冗余,每次扩展一个方法,都要写一次原型对象,我们可以把原型对象prototype当做一个字面量对象,所有的方法都在字面

量对象中扩展,可以达到同样的效果:

 1         CreateObj.prototype = {
 2             showUserAge : function(){
 3                 return this.userAge;
 4             },
 5             showUserName : function(){
 6                 return this.userName;
 7             },
 8         }
 9         var obj1 = new CreateObj( "ghostwu", 22 );
10         var obj2 = new CreateObj( "卫庄", 24 );
11         console.log( obj1.showUserName(), obj1.showUserAge() ); //ghostwu 22
12         console.log( obj2.showUserName(), obj2.showUserAge() ); //卫庄 24

但是这种原型(prototype)对象的写法,属于重写了CreateObj的默认原型对象,造成的第一个问题就是constructor不再指向CreateObj.

没有重写之前,constructor指向CreateObj

 1         function CreateObj( uName, uAge ) {
 2             this.userName = uName;
 3             this.userAge = uAge;
 4         }
 5         CreateObj.prototype.showUserName = function () {
 6             return this.userName;
 7         }
 8         CreateObj.prototype.showUserAge = function () {
 9             return this.userAge;
10         }
11         console.log( CreateObj.prototype.constructor === CreateObj ); //true

重写之后,constructor指向Object

 1         CreateObj.prototype = {
 2             showUserAge : function(){
 3                 return this.userAge;
 4             },
 5             showUserName : function(){
 6                 return this.userName;
 7             },
 8         }
 9         console.log( CreateObj.prototype.constructor === CreateObj ); //false
10         console.log( CreateObj.prototype.constructor === Object ); //true

所以说,constructor不能准确的标识对象,因为他会被修改

我们之前写的程序,基本都是在原型对象(prototype)上扩展完了方法之后,再实例化对象,我们看下,先实例化对象,再在原型对象(prototype)上扩展函数,

实例对象是否能正常的调用到扩展的方法?

1         function CreateObj( uName, uAge ) {
2             this.userName = uName;
3             this.userAge = uAge;
4         }
5         var obj1 = new CreateObj( "ghostwu", 22 );
6         CreateObj.prototype.showUserName = function(){
7             return this.userName;
8         }
9         console.log( obj1.showUserName() ); //ghostwu

可以正常调用,但是,如果原型对象是重写的,就调用不到了

 1         function CreateObj( uName, uAge ) {
 2             this.userName = uName;
 3             this.userAge = uAge;
 4         }
 5         var obj1 = new CreateObj( "ghostwu", 22 );
 6         CreateObj.prototype = {
 7             showUserName : function(){
 8                 return this.userName;
 9             }
10         }
11         console.log( obj1.showUserName() ); //报错

因为重写了原型对象之后,同时实例化又是在重写之前发生的,所以实例的隐式原型__proto__不会指向重写的原型对象,所以就调用不到

另一个问题,如果在原型对象(prototype)上有引用类型,千万小心,因为多个实例共用原型对象,只要有一个实例改变了引用类型的值,其他实例全部会收到

改变之后的结果。

1         function CreateObj(){}
2         CreateObj.prototype = {
3             name : "ghostwu",
4             skills : [ "php", "javascript", "linux" ]
5         };
6         var obj1 = new CreateObj();
7         obj1.skills.push( "python" );
8         var obj2 = new CreateObj();
9         console.log( obj2.skills ); //"php", "javascript", "linux", "python"

原型对象(prototype)的共享特性,可以很方便的为一些内置的对象扩展一些方法,比如,数组去重复

 1         Array.prototype.unique = function(){
 2             var res = [];
 3             for( var i = 0, len = this.length; i < len; i++ ){
 4                 if( res.indexOf( this[i] ) == -1 ) {
 5                    res.push( this[i] ); 
 6                 }
 7             }
 8             return res;
 9         }
10         var arr = [ 10, 20, 30, 20, 30, 20, 40, 20 ];
11         console.log( arr.unique() ); //10, 20, 30, 40

但是,不要随便往内置的对象上面扩展方法,在多人协作开发,很容易产生覆盖,以及污染.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85147.html

相关文章

  • [js高手之路]原型对象(prototype)与原型链相关属性与方法详解

    摘要:一,检测左侧的原型链上,是否存在右侧的原型我在之前的两篇文章高手之路构造函数的基本特性与优缺点高手之路一步步图解的原型对象原型链已经分享过了卫庄二如果隐式原型指向调用方法的对象原型那么这个方法就返回,如卫庄因为的隐式原型指向的都是,有朋友可 一,instanceof: instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型. 我在之前的两篇文章 ...

    svtter 评论0 收藏0
  • [js高手之路]构造函数基本特性与优缺点

    摘要:所以一句话理解的运算规则为检测左侧的原型链上,是否存在右侧的原型。 上文,通过基本的对象创建问题了解了构造函数,本文,我们接着上文继续了解构造函数的基本特性,以及优缺点. 每个对象上面都有一个constructor属性( 严格意义上来说,是原型上的,对象是通过查找到原型找到 constructor属性 ).后面讲到原型的时候,我会用示意图的方式说明 1 functio...

    Ajian 评论0 收藏0
  • [js高手之路] es6系列教程 - 新类语法实战选项卡

    摘要:其实的面向对象很多原理和机制还是的,只不过把语法改成类似和老牌后端语言中的面向对象语法一用封装一个基本的类是不是很向和中的类其实本质还是原型链,我们往下看就知道了首先说下语法规则中的就是类名,可以自定义就是构造函数,这个是关键字,当实例化对 其实es6的面向对象很多原理和机制还是ES5的,只不过把语法改成类似php和java老牌后端语言中的面向对象语法. 一、用es6封装一个基本的类 ...

    yintaolaowanzi 评论0 收藏0
  • [js高手之路]js单页hash路由原理与应用实战

    摘要:什么是路由通俗点说,就是不同的显示不同的内容什么是单页应用单页,英文缩写为,就是把各种功能做在一个页面内那所谓的单页路由应用就是在一个页面内,通过切换地址栏的来实现切换内容的变化如何知道切换了呢当后面的锚文本发生变化时,会触发事件。 什么是路由? 通俗点说,就是不同的URL显示不同的内容 什么是单页应用? 单页,英文缩写为SPA( Single Page Application),就是...

    tinna 评论0 收藏0
  • 面向对象JavaScript(如何一步步成为js高手

    摘要:虽然,也是面向疾苦的语言,但是,它和静态类型语言的面向接口编程不一而足。对象对他自己的行为负责,其他对象不关心它的内部实现。 ‘工欲善其事,必先利其器’,在深入学习JavaScript之前,我认为我们很有必要了解以下,JavaScript这门面向对象的动态语言到底是一门什么样的语言。 JavaScript vs 其他面向对象语言 它没有使用像Java等传统的面向对象语言的类式继承,而...

    peixn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<