js使用原型对象(prototype)需要注意的地方


Posted in Javascript onAugust 28, 2017

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 Javascript
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
Apr 20 Javascript
JavaScript检测浏览器cookie是否已经启动的方法
Feb 27 Javascript
深入剖析JavaScript编程中的对象概念
Oct 21 Javascript
全面详细的jQuery常见开发技巧手册
Feb 21 Javascript
javascript如何定义对象数组
Jun 07 Javascript
javascript输出AscII码扩展集中的字符方法
Dec 26 Javascript
jquery精度计算代码 jquery指定精确小数位
Feb 06 Javascript
node中koa中间件机制详解
Aug 22 Javascript
js实现继承的方法及优缺点总结
May 08 Javascript
jQuery弹框插件使用方法详解
May 26 jQuery
javascript实现计算器功能详解流程
Nov 01 Javascript
vue2.0移除或更改的一些东西(移除index key)
Aug 28 #Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
Aug 28 #Javascript
JS实现图片手风琴效果
Apr 17 #Javascript
vue服务端渲染的实例代码
Aug 28 #Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
Aug 28 #jQuery
使用react-router4.0实现重定向和404功能的方法
Aug 28 #Javascript
vue.js路由跳转详解
Aug 28 #Javascript
You might like
基于PHP+MySQL的聊天室设计
2006/10/09 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
2011/09/19 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
改变javascript函数内部this指针指向的三种方法
2010/04/23 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
基于jquery实现省市联动效果
2015/11/23 Javascript
详解基于Bootstrap扁平化的后台框架Ace
2015/11/27 Javascript
JavaScript 节流函数 Throttle 详解
2016/07/04 Javascript
js中遍历Map对象的简单实例
2016/08/08 Javascript
利用jquery实现瀑布流3种案例
2016/09/18 Javascript
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
解决angularjs中同步执行http请求的方法
2018/08/13 Javascript
Vue Promise的axios请求封装详解
2018/08/13 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
2018/09/19 Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
2018/11/26 Javascript
使用zrender.js绘制体温单效果
2019/10/31 Javascript
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
简单介绍Python的轻便web框架Bottle
2015/04/08 Python
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
python之Socket网络编程详解
2016/09/29 Python
matplotlib subplots 调整子图间矩的实例
2018/05/25 Python
python版opencv摄像头人脸实时检测方法
2018/08/03 Python
使用python读取.text文件特定行的数据方法
2019/01/28 Python
PyTorch中Tensor的拼接与拆分的实现
2019/08/18 Python
python通过移动端访问查看电脑界面
2020/01/06 Python
Pytorch 使用不同版本的cuda的方法步骤
2020/04/02 Python
pandas数据处理之绘图的实现
2020/06/15 Python
django跳转页面传参的实现
2020/09/17 Python
党的群众路线教育实践活动查摆问题自查报告
2014/10/10 职场文书
煤矿安全保证书
2015/02/27 职场文书
2015年党员个人工作总结
2015/05/13 职场文书
2016猴年春节慰问信
2015/11/30 职场文书
Jsonp劫持学习
2021/04/01 PHP
JavaScript实现优先级队列
2021/12/06 Javascript
Java中try catch处理异常示例
2021/12/06 Java/Android