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 相关文章推荐
Jquery 基础学习笔记之文档处理
May 29 Javascript
js png图片(有含有透明)在IE6中为什么不透明了
Feb 07 Javascript
JavaScript异步加载浅析
Dec 28 Javascript
JavaScript获取当前网页标题(title)的方法
Apr 03 Javascript
jQuery表单美化插件jqTransform使用详解
Apr 12 Javascript
js实现鼠标滑过文字链接色彩变化的效果
May 06 Javascript
javascript中CheckBox全选终极方案
May 20 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
Jan 04 Javascript
详解Node.js如何开发命令行工具
Aug 14 Javascript
jQuery使用JSONP实现跨域获取数据的三种方法详解
May 04 jQuery
jQuery实现的淡入淡出图片轮播效果示例
Aug 29 jQuery
vue 使用rules对表单字段进行校验的步骤
Dec 25 Vue.js
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
使用zend studio for eclipse不能激活代码提示功能的解决办法
2009/10/11 PHP
PHP数组传递是值传递而非引用传递概念纠正
2013/01/31 PHP
显示程序执行时间php函数代码
2013/08/29 PHP
PHP中的替代语法介绍
2015/01/09 PHP
php实现微信扫码支付
2017/03/26 PHP
yii2学习教程之5种内置行为类详解
2017/08/03 PHP
jQuery 跨域访问问题解决方法
2009/12/02 Javascript
理解Javascript_14_函数形式参数与arguments
2010/10/20 Javascript
JQuery中html()方法使用不当带来的陷阱
2011/04/07 Javascript
JS实现图片预加载无需等待
2012/12/21 Javascript
jquery读取xml文件实现省市县三级联动的方法
2015/05/29 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
request请求获取参数的实现方法(post和get两种方式)
2016/09/27 Javascript
浅析如何利用JavaScript进行语音识别
2016/10/27 Javascript
基于vue.js实现图片轮播效果
2016/12/01 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
EasyUI实现下拉框多选功能
2017/11/07 Javascript
vue组件tabbar使用方法详解
2018/11/06 Javascript
Vuex实现数据增加和删除功能
2019/11/11 Javascript
Vue简单封装axios之解决post请求后端接收不到参数问题
2020/02/16 Javascript
[43:24]VG vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
Python中Iterator迭代器的使用杂谈
2016/06/20 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
2019/06/26 Python
Python如何将字符串转换为日期
2020/07/31 Python
如何用python免费看美剧
2020/08/11 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
2020/12/04 Python
css3 position fixed固定居中问题解决方案
2014/08/19 HTML / CSS
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
如何查看在weblogic中已经发布的EJB
2012/06/01 面试题
环保志愿者活动总结
2014/06/27 职场文书
岗位职责说明书模板
2014/07/30 职场文书
大学生党校培训心得体会
2014/09/11 职场文书
超级礼物观后感
2015/06/15 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
《自然之道》读后感3篇
2019/12/17 职场文书