详谈js原型继承的一些问题


Posted in Javascript onSeptember 06, 2017

当我们使用原型链继承时,需要谨慎的定义原型上的方法和属性,因为这可能带来意外的结果。

一、谨慎的定义原型上的方法。

当我们想为一个构造函数的原型上定义一个方法时,一定要在更改原型后再定义,否则新的原型对象上不会有定义的这个方法,导致与我们预期的结果不同。例:

function superObj(){}
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
};
superObj.prototype={
  name:'Poly'
};
var obj=new superObj();
obj.sayHi();//报错!! superObj.sayHi is not a function

正确操作如下

function superObj(){}
superObj.prototype={
  name:'Poly'
};
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
};
var obj=new superObj();
obj.sayHi();// 'hi'

二、不要使用对象字面量给原型创建属性/方法。

使用对象字面量,就会新创建一个对象,并把新对象的引用地址赋值给构造函数的prototype。例

function superObj(){}
superObj.prototype={
  sayHi:function sayHi(){
    console.log('hi');
  }
}

正确操作如下:

function superObj(){}
superObj.prototype.sayHi=function sayHi(){
  console.log('hi');
}

三、对象实例与原型存在直接对应关系。

意思就是说当一个对__proto__就会保存原型的引用地址,即使构造函数的prototype发生改变,也不会对之前创建的实例中的__proto__产生影响。例

function superObj(){}
superObj.prototype.say=function() {
  console.log('hello');
}
var obj=new superObj();
superObj.prototype={
  say:function() {
    console.log('world');
  }
};
var obj2=new superObj();
obj.say();//'hello'
obj2.say();//'world'

四、最好不要给原型上定义值为引用类型的属性。

如果在原型上定义值为引用类型的属性,那么所有实例都会共享该属性值(引用类型值,指向同一个对象),当其中一个实例修改该引用类型上的值或属性时,所有实例上的都会发生改变。因此值为引用类型的属性,最好在构造函数中定义。例

function superObj(){}
superObj.prototype.ary=[1,2,3];
var obj1=new superObj();
var obj2=new superObj();
obj1.ary[0]=0;//obj1.ary和obj2.ary指向的是同一个数组,当obj1修改此数组时,obj2.ary也会发生改变
console.log(obj2.ary[0]);//0

如果不想让实例共享同一个引用对象,那么就应该在构造函数中进行定义。例

function superObj(){
  this.ary=[1,2,3];
}
var obj1=new superObj();
var obj2=new superObj();
obj1.ary[0]=0;//obj1.ary和obj2.ary指向的不是同一个数组,所以修改obj1.ary不会影响obj2.ary
console.log(obj2.ary[0]);//1

以上这篇详谈js原型继承的一些问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery LigerUI 使用教程入门篇
Jan 18 Javascript
JQuery实现鼠标移动到图片上显示边框效果
Jan 09 Javascript
jQuery使用height()获取高度需要注意的地方
Dec 13 Javascript
jQuery构造函数init参数分析
May 13 Javascript
轻松理解JavaScript之AJAX
Mar 15 Javascript
JS字符串统计操作示例【遍历,截取,输出,计算】
Mar 27 Javascript
vue全局组件与局部组件使用方法详解
Mar 29 Javascript
使用vuex的state状态对象的5种方式
Apr 19 Javascript
原生js实现3D轮播图
Mar 21 Javascript
js实现旋转木马轮播图效果
Jan 10 Javascript
js实现烟花特效
Mar 02 Javascript
vue实现评价星星功能
Jun 30 Javascript
浅谈react.js中实现tab吸顶效果的问题
Sep 06 #Javascript
vue组件初学_弹射小球(实例讲解)
Sep 06 #Javascript
node.js-v6新版安装具体步骤(分享)
Sep 06 #Javascript
Angular2里获取(input file)上传文件的内容的方法
Sep 05 #Javascript
浅谈angular4生命周期钩子
Sep 05 #Javascript
webpack踩坑之路图片的路径与打包
Sep 05 #Javascript
js实现鼠标跟随运动效果
Aug 02 #Javascript
You might like
用PHP编程语言开发动态WAP页面
2006/10/09 PHP
PHP 创建标签云函数代码
2010/05/26 PHP
php读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
PHP中函数rand和mt_rand的区别比较
2012/12/26 PHP
Ajax+PHP快速上手及简单应用说明
2013/07/24 PHP
php简单复制文件的方法
2016/05/09 PHP
JS控制表格隔行变色
2006/06/26 Javascript
javascript处理table表格的代码
2010/12/06 Javascript
jquery高效反选具体实现
2013/05/05 Javascript
JQuery获取表格数据示例代码
2014/05/26 Javascript
JS判断字符串包含的方法
2015/05/05 Javascript
js密码强度实时检测代码
2016/03/02 Javascript
js字符串截取函数slice、substring和substr的比较
2016/05/17 Javascript
Vue监听数组变化源码解析
2017/03/09 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
vue 解决循环引用组件报错的问题
2018/09/06 Javascript
[05:15]DOTA2英雄梦之声_第16期_灰烬之灵
2014/06/21 DOTA
[00:57]深扒TI7聊天轮盘语音出处5
2017/05/11 DOTA
Python  连接字符串(join %)
2008/09/06 Python
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
Python 实现异步调用函数的示例讲解
2018/10/14 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
2019/05/10 Python
python @classmethod 的使用场合详解
2019/08/23 Python
python实现xml转json文件的示例代码
2020/12/30 Python
css3 按钮 利用css3实现超酷下载按钮
2013/03/18 HTML / CSS
IRO美国官网:法国服装品牌
2018/03/06 全球购物
函授本科毕业自我鉴定
2013/10/09 职场文书
QA工程师岗位职责
2013/11/20 职场文书
广告业务员岗位职责
2014/02/06 职场文书
单位绩效考核方案
2014/05/11 职场文书
机械专业求职信范文
2014/07/15 职场文书
党员个人剖析材料2014
2014/10/08 职场文书
社区四风存在问题及整改措施
2014/10/26 职场文书
介绍信格式
2015/01/30 职场文书
网吧管理制度范本
2015/08/05 职场文书