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 相关文章推荐
javascript倒计时功能实现代码
Jun 07 Javascript
由ReactJS的Hello world说开来
Jul 02 Javascript
javascript检查浏览器是否已经启用XX功能
Jul 10 Javascript
JS截取与分割字符串常用技巧总结
Nov 10 Javascript
js表单中选择框值的获取及表单的序列化
Dec 17 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
May 16 Javascript
jquery实现简单的瀑布流布局
Dec 11 Javascript
vue.js如何将echarts封装为组件一键使用详解
Oct 10 Javascript
Three.js开发实现3D地图的实践过程总结
Nov 20 Javascript
vue2.0.js的多级联动选择器实现方法
Feb 09 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
Sep 28 Javascript
加速vue组件渲染之性能优化
Apr 09 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
学习使用curl采集curl使用方法
2012/01/11 PHP
php通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
利用js动态添加删除table行的示例代码
2013/12/16 Javascript
JavaScript中数据结构与算法(四):串(BF)
2015/06/19 Javascript
基于javascript实现窗口抖动效果
2016/01/03 Javascript
JavaScript每天必学之事件
2016/09/18 Javascript
JS DOMReady事件的六种实现方法总结
2016/11/23 Javascript
js中动态创建json,动态为json添加属性、属性值的实例
2016/12/02 Javascript
JavaScript之面向对象_动力节点Java学院整理
2017/06/29 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
原生js实现的移动端可拖动进度条插件功能详解
2019/08/15 Javascript
vue登录注册实例详解
2019/09/14 Javascript
一起深入理解js中的事件对象
2021/02/06 Javascript
Python实现学生成绩管理系统
2020/04/05 Python
利用Python如何实现数据驱动的接口自动化测试
2018/05/11 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
2019/08/05 Python
numpy.random.shuffle打乱顺序函数的实现
2019/09/10 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
Python post请求实现代码实例
2020/02/28 Python
使用Python pip怎么升级pip
2020/08/11 Python
软件设计的目标是什么
2016/12/04 面试题
教师自荐信范文
2013/12/09 职场文书
物流专业求职计划书
2014/01/10 职场文书
致百米运动员广播稿
2014/01/29 职场文书
餐厅楼面部长岗位职责范文
2014/02/16 职场文书
小学生爱国演讲稿
2014/04/25 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
鸡毛信观后感
2015/06/11 职场文书
写作技巧:怎样写好一份优秀工作总结?
2019/08/14 职场文书
2019年健身俱乐部的创业计划书
2019/08/26 职场文书
在JavaScript中如何使用宏详解
2021/05/06 Javascript
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏
Tomcat配置访问日志和线程数
2022/05/06 Servers