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 相关文章推荐
web 页面分页打印的实现
Jun 22 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
Aug 04 Javascript
js运动动画的八个知识点
Mar 12 Javascript
jQuery插件expander实现图片翻转特效
May 21 Javascript
有关easyui-layout中的收缩层无法显示标题的解决办法
May 10 Javascript
jQuery中fadein与fadeout方法用法示例
Sep 16 Javascript
AngularJS+bootstrap实现动态选择商品功能示例
May 17 Javascript
vue webpack实用技巧总结
Apr 24 Javascript
Angular中的ng-template及angular 使用ngTemplateOutlet 指令的方法
Aug 08 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
Feb 19 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
Jan 18 Javascript
Vue的data、computed、watch源码浅谈
Apr 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
德生PL330测评
2021/03/02 无线电
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
2011/03/23 PHP
smarty 缓存控制前的页面静态化原理
2013/03/15 PHP
PHP中文乱码解决方案
2015/03/05 PHP
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
php判断是否为ajax请求的方法
2016/11/29 PHP
PHP大文件分块上传功能实例详解
2019/07/22 PHP
JS正则中的RegExp对象对象
2012/11/07 Javascript
JavaScript事件处理器中的event参数使用介绍
2013/05/24 Javascript
JavaScript动态添加事件之事件委托
2016/07/12 Javascript
使用jquery判断一个元素是否含有一个指定的类(class)实例
2017/02/12 Javascript
jQuery实现三级联动效果
2017/03/02 Javascript
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
2018/05/10 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
[00:36]DOTA2上海特级锦标赛 Archon战队宣传片
2016/03/04 DOTA
python实现的守护进程(Daemon)用法实例
2015/06/02 Python
Python3实现爬取指定百度贴吧页面并保存页面数据生成本地文档的方法
2018/04/22 Python
python简单区块链模拟详解
2019/07/03 Python
Django 实现前端图片压缩功能的方法
2019/08/07 Python
Python数据库小程序源代码
2019/09/15 Python
Pycharm连接远程服务器过程图解
2020/04/30 Python
python怎么提高计算速度
2020/06/11 Python
python实现无边框进度条的实例代码
2020/12/30 Python
Lacoste美国官网:经典POLO衫品牌
2016/10/12 全球购物
手机配件第一品牌:ZAGG
2017/05/28 全球购物
台湾母婴用品购物网站:Infant婴之房
2018/06/15 全球购物
Manduka官网:瑜伽垫、瑜伽毛巾和服装
2018/07/02 全球购物
德国的各种媒体在线商店:Thalia.de(书籍、电子书、玩具等)
2020/10/08 全球购物
王老吉广告词
2014/03/20 职场文书
保护环境建议书300字
2014/05/13 职场文书
办理收楼委托书范本
2014/10/09 职场文书
先进教师个人事迹材料
2014/12/15 职场文书
2015年教师节演讲稿范文
2015/03/19 职场文书
2015年学校党支部工作总结
2015/04/01 职场文书
2015年电工工作总结
2015/04/10 职场文书