javascript 用函数实现继承详解


Posted in Javascript onMay 28, 2016

一、知识储备:

1、枚举属性名称的函数:

(1)for...in:可以在循环体中遍历对象中所有可枚举的属性(包括自有属性和继承属性)

(2)Object.keys():返回数组(可枚举的自有属性)

(3)Object.getOwnPropertyNames():所有的自有属性

3、属性的特性:数据属性和存取器属性

(1)数据属性:可写(writable)  可枚举(enumerable)  可配置(configurable)  值(value)

数据属性只有一个简单的值;

(2)存取器属性: 写入(set)  读取(get)  可枚举(enumerable)  可配置(configurable)

存取器属性不可写(即没有writable特性)。

属性有set方法,那这个属性是可写的,有get方法,那这个属性就是可读的。

4、定义属性特性的方法:Object.defineProperty(对象,属性,描述符对象)

5、获取属性的描述符对象:Object.getOwnPropertyDescriptor(对象,属性)

二、示例

1、根据for...in的用法,我们可以写出模拟“继承”的方法:

<script type="text/javascript"> 
  var child={}; 
  var mother={ 
    name:"zhangzhiying", 
    lastAge:21, 
    sex:"女"
  }; 
  function extend(target,source){ 
  
for(var p in source){ 
    
target[p]=source[p]; 
  

} 
  

return target; 
  } 
  extend(child,mother); 
  console.log(child);   //<STRONG>Object {name: "zhangzhiying", lastAge: 21, sex: "女"}</STRONG> 
</script>

2、使用for in来循环遍历原型对象的属性,然后一一赋值给我们的空对象,从而实现了“继承”。这个思路很正确,下面我们来对以上示例进行改造:

<script type="text/javascript"> 
  var child={}; 
  var mother={ 
    name:"zhangzhiying", 
    lastAge:21, 
    <STRONG>set age(value){ 
      this.lastAge=value; 
    }, 
    get age(){ 
      return this.lastAge+1; 
    },</STRONG> 
    sex:"女"
  };<BR>
<STRONG> mother.age=15;</STRONG>    //有set方法,具有可写性 
  function extend(target,source){ 
  

for(var p in source){ 
    
target[p]=source[p]; 
  

} 
  

return target; 
  } 
  extend(child,mother); 
  console.log(child);  //<STRONG>Object {name: "zhangzhiying", lastAge: 15, age: 16, sex: "女"}</STRONG> 
</script>

可以看到代码中使用了一对set,get;其中age是一个存取器属性。

运行的结果:一个不包含set,get的普通对象。 

结论:for  in实现的“继承”不处理set和get ,它把存取器属性(age)转换为一个静态的数据属性。

3、给mother对象设置数据属性

<script type="text/javascript"> 
  var child={}; 
  var mother={ 
    name:"zhangzhiying", 
    lastAge:21, 
    set age(value){ 
      this.lastAge=value; 
    }, 
    get age(){ 
      return this.lastAge+1; 
    }, 
    sex:"女"
  }; 
  Object.defineProperty(mother,"lastAge",{writable:false}); //把lastAge设置成了不可写 
  mother.age=15;                       //设置无效,因为lastAge的值不变,所以lastAge+1不变,即age不变 
  function extend(target,source){ 
    for(var p in source){ 
    target[p]=source[p]; 
  } 
  return target; 
  } 
  extend(child,mother); 
  console.log(child);   //Object {name: "zhangzhiying", lastAge: 21, age: 22, sex: "女"} 
  child.lastAge=12;
//结果显示lastAge改变,说明child.lastAge没有“继承”到mother.lastAge的特性,我们再用getOwnPropertyDesriptor()方法确认一下<BR>

 console.log(Object.getO
<EM id=__mceDel></script> 
</EM>

结论:要实现继承,我们还需要解决的问题->“继承”属性特性。

4、完善版本 

<script type="text/javascript"> 
  var child={}; 
  var mother={ 
    name:"zhangzhiying", 
    lastAge:21, 
    set age(value){ 
      this.lastAge=value; 
    }, 
    get age(){ 
      return this.lastAge+1; 
    }, 
    sex:"女"
  }; 
  Object.defineProperty(mother,"lastAge",{writable:false}); 
  mother.age=15; 
  <SPAN style="COLOR: #333399"><STRONG>function extend(target,source){ 
    var names=Object.getOwnPropertyNames(source);  //获取所有的属性名 
    for(var i=0;i<names.length;i++){ 
      if(names[i] in target) continue;  //如果这个属性存在,就跳过(原型继承中,如果自有属性和原型对象的属性重名,保留自有属性) 
      var desc=Object.getOwnPropertyDescriptor(source,names[i]);  //获取mother属性的描述符对象(即属性特性的集合,es5中用描述符对象来表示) 
      Object.defineProperty(target,names[i],desc);  //将mother的描述符对象给child的属性定义 
    } 
    return target; 
  }</STRONG></SPAN> 
  extend(child,mother); 
  console.log(child); 
  child.lastAge=12; 
  console.log(Object.getOwnPropertyDescriptor(child,"lastAge")); 
  console.log(child); 
</script>

最后的结果:

javascript 用函数实现继承详解

可以明显看到三次的打印,child“继承”到了set和get,lastAge数值没发生变化,writable也是false了。 

总结:最近在看《javascript权威指南》,总结一点心得,有错误欢迎指正,共同学习进步~

以上这篇javascript 用函数实现继承详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 树形导航菜单实例代码
Aug 13 Javascript
jquery教程ajax请求json数据示例
Jan 13 Javascript
js调用iframe实现打印页面内容的方法
Mar 04 Javascript
再谈JavaScript线程
Jul 10 Javascript
JavaScript中的定时器之Item23的合理使用
Oct 30 Javascript
JavaScript中日期函数的相关操作知识
Aug 03 Javascript
使用JS轻松实现ionic调用键盘搜索功能(超实用)
Sep 06 Javascript
react-router JS 控制路由跳转实例
Jun 15 Javascript
jQuery序列化后的表单值转换成Json
Jun 16 jQuery
vue-cli下的vuex的简单Demo图解(实现加1减1操作)
Feb 26 Javascript
jquery获取并修改触发事件的DOM元素示例【基于target 属性】
Oct 10 jQuery
vant-ui组件调用Dialog弹窗异步关闭操作
Nov 04 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
May 28 #Javascript
jQuery实现布局高宽自适应的简单实例
May 28 #Javascript
jquery mobile界面数据刷新的实现方法
May 28 #Javascript
jquery自适应布局的简单实例
May 28 #Javascript
JQuery Mobile 弹出式登录框的实现方法
May 28 #Javascript
jquery div模态窗口的简单实例
May 28 #Javascript
JavaScript 弹出子窗体并返回结果到父窗体的实现代码
May 28 #Javascript
You might like
最省空间的计数器
2006/10/09 PHP
PHP新手上路(十四)
2006/10/09 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
2016/05/16 PHP
PHP自定义序列化接口Serializable用法分析
2017/12/29 PHP
PHP中cookie知识点学习
2018/05/06 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
js jquery ajax的几种用法总结(及优缺点介绍)
2014/01/28 Javascript
node.js中的console.assert方法使用说明
2014/12/10 Javascript
javascript结合fileReader 实现上传图片
2015/01/30 Javascript
浅谈JavaScript中的String对象常用方法
2015/02/25 Javascript
JavaScript调用浏览器打印功能实例分析
2015/07/17 Javascript
javascript实现保留两位小数的多种方法
2015/12/18 Javascript
完美实现js选项卡切换效果(一)
2017/03/08 Javascript
详解在React项目中安装并使用Less(用法总结)
2019/03/18 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
VUE的history模式下除了index外其他路由404报错解决办法
2019/08/21 Javascript
JS window对象简单操作完整示例
2020/01/14 Javascript
javascript解析json格式的数据方法详解
2020/08/07 Javascript
python解析xml文件操作实例
2014/10/05 Python
Python对象体系深入分析
2014/10/28 Python
python将回车作为输入内容的实例
2018/06/23 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
python按键按住不放持续响应的实例代码
2019/07/17 Python
Django框架反向解析操作详解
2019/11/28 Python
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
美国手工艺品市场的领导者:Annie’s
2019/04/04 全球购物
小学运动会表扬稿
2014/01/19 职场文书
保护母亲河倡议书
2014/04/14 职场文书
三方合作协议书范本
2014/04/18 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
创建绿色社区汇报材料
2014/08/22 职场文书
六年级数学教学反思
2016/02/16 职场文书
Python字典和列表性能之间的比较
2021/06/07 Python
Vue h函数的使用详解
2022/02/18 Vue.js
使用Redis做预定库存缓存功能
2022/04/02 Redis
Win11开始菜单添加休眠选项
2022/04/19 数码科技