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 单例/单体模式(Singleton)
Apr 07 Javascript
JavaScript中最简洁的编码html字符串的方法
Oct 11 Javascript
jquery利用命名空间移除绑定事件的方法
Mar 11 Javascript
jQuery实现鼠标经过事件的延时处理效果
Aug 20 Javascript
asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
May 05 Javascript
详解vue.js数据传递以及数据分发slot
Jan 20 Javascript
详解Angular如何正确的操作DOM
Jul 06 Javascript
jQuery Migrate 插件用法实例详解
May 22 jQuery
5分钟快速看懂ES6中的反射与代理
Dec 19 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
Jul 22 Javascript
vue 监听 Treeselect 选择项的改变操作
Aug 31 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
Sep 02 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
FCKeditor添加自定义按钮
2008/03/27 PHP
PHP读取文件内容后清空文件示例代码
2014/03/18 PHP
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
在WordPress中使用wp-cron插件来设置定时任务
2015/12/10 PHP
PHP序列化操作方法分析
2016/09/28 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
2014/04/04 Javascript
JavaScript学习笔记之Cookie对象
2015/01/22 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
利用vue + koa2 + mockjs模拟数据的方法教程
2017/11/22 Javascript
uniapp电商小程序实现订单30分钟倒计时
2020/11/01 Javascript
[02:35]DOTA2英雄基础教程 末日使者
2013/12/04 DOTA
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
在Python中使用异步Socket编程性能测试
2014/06/25 Python
Python实现的一个找零钱的小程序代码分享
2014/08/25 Python
python实现猜单词小游戏
2020/05/22 Python
Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】
2019/04/05 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
一款利用html5和css3实现的3D滚动特效的教程
2015/01/04 HTML / CSS
HTML5实现签到 功能
2018/10/09 HTML / CSS
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
htmlentities() 和 htmlspecialchars()有什么区别
2015/07/01 面试题
国外软件测试工程师面试题
2016/12/09 面试题
应用电子专业学生的自我评价
2013/10/16 职场文书
标准导师推荐信(医学类)
2013/10/28 职场文书
会计系个人求职信范文分享
2013/12/20 职场文书
小学科学教学反思
2014/01/26 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
2014年乡镇领导个人整改措施
2014/09/19 职场文书
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
业务员辞职信范文
2015/03/02 职场文书
强烈推荐:小学生:暑假作息时间表(值得收藏)
2019/07/09 职场文书
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫
CSS使用Flex和Grid布局实现3D骰子
2022/08/05 HTML / CSS