深入了解javascript中的prototype与继承


Posted in Javascript onApril 14, 2013

通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性列表。javascript创建对象时采用了写时复制的理念。
只有构造器才具有prototype属性,原型链继承就是创建一个新的指针,指向构造器的prototype属性。
prototype属性之所以特别,是因为javascript时读取属性时的遍历机制决定的。本质上它就是一个普通的指针。

构造器包括:
1.Object
2.Function
3.Array
4.Date
5.String

下面我们来举一些例子吧

<script> 
//每个function都有一个默认的属性prototype,而这个prototype的constructor默认指向这个函数
//注意Person.constructor 不等于 Person.prototype.constructor. Function实例自带constructor属性 
   function Person(name) {  
        this.name = name;  
    };  
    Person.prototype.getName = function() {  
        return this.name;  
    };  
    var p = new Person("ZhangSan");      console.log(Person.prototype.constructor === Person); // true  
    console.log(p.constructor === Person);  // true ,这是因为p本身不包含constructor属性,所以这里其实调用的是Person.prototype.constructor     
</script>

我们的目的是要表示
1.表明Person继承自Animal
2. 表明p2是Person的实例

我们修改一下prototype属性的指向,让Person能获取Animal中的prototype属性中的方法。也就是Person继承自Animal(人是野兽)

<script> 
   function Person(name) {  
        this.name = name;  
    };  
    Person.prototype.getName = function() {  
        return this.name;  
    };  
    var p1 = new Person("ZhangSan");      console.log(p.constructor === Person);  // true  
    console.log(Person.prototype.constructor === Person); // true  

     function Animal(){ } 
     Person.prototype = new Animal();//之所以不采用Person.prototype  = Animal.prototype,是因为new 还有其他功能,最后总结。 
     var p2 = new Person("ZhangSan"); 
//(p2 -> Person.prototype -> Animal.prototype, 所以p2.constructor其实就是Animal.prototype.constructor)
     console.log(p2.constructor === Person);  // 输出为false ,但我们的本意是要这里为true的,表明p2是Person的实例。此时目的1达到了,目的2没达到。 
</script>

但如果我们这么修正
 
Person.prototype = new Animal();
Person.prototype.constructor = Person;

这时p2.consturctor是对了,指向的是Person,表示p2是Person类的实例,但是新问题出现了。此时目的2达到了,目的1没达到。
目的1和目的2此时互相矛盾,是因为此时prototype表达了矛盾的两个意思,
1表示父类是谁
2作为自己实例的原型来复制

因此我们不能直接使用prototype属性来表示父类是谁,而是用getPrototypeOf()方法来知道父类是谁。

Person.prototype = new Animal();Person.prototype.constructor = Person;
var p2 = new Person("ZhangSan"); 
p2.constructor     //显示 function Person() {}
Object.getPrototypeOf(Person.prototype).constructor     //显示 function Animal() {}

就把这两个概念给分开了

最后总结一下:
当代码var p = new Person()执行时,new 做了如下几件事情:

创建一个空白对象

创建一个指向Person.prototype的指针

将这个对象通过this关键字传递到构造函数中并执行构造函数。

如果采用Person.prototype  = Animal.prototype来表示Person继承自Animal, instanceof方法也同样会显示p也是Animal的实例,返回为true.之所以不采用此方法,是因为下面两个原因:

1.new 创建了一个新对象,这样就避免了设置Person.prototype.constructor = Person 的时候也会导致Animal.prototype.constructor的值变为Person,而是动态给这个新创建的对象一个constructor实例属性,这样实例上的属性constructor就覆盖了Animal.prototype.constructor,这样Person.prototype.constructor和Animal.prototype.contructor就分开了。

2.Animal自身的this对象的属性没办法传递给Person

通过使用 hasOwnProperty()方法,什么时候访问的是实例属性,什么时候访问的是原型属性就 一清二楚了。
 

Javascript 相关文章推荐
JAVASCRIPT style 中visibility和display之间的区别
Jan 22 Javascript
ASP.NET jQuery 实例2 (表单中使用回车在TextBox之间向下移动)
Jan 13 Javascript
THREE.JS入门教程(1)THREE.JS使用前了解
Jan 24 Javascript
node.js 开发指南 ? Node.js 连接 MySQL 并进行数据库操作
Jul 29 Javascript
jQuery获取iframe的document对象的方法
Oct 10 Javascript
jQuery插件简单实现方法
Jul 18 Javascript
jquery左右全屏大尺寸多图滑动效果代码分享
Aug 28 Javascript
springmvc接收jquery提交的数组数据代码分享
Oct 28 jQuery
vue项目部署上线遇到的问题及解决方法
Jun 10 Javascript
nuxt中使用路由守卫的方法步骤
Jan 27 Javascript
vue Treeselect下拉树只能选择第N级元素实现代码
Aug 31 Javascript
Selenium执行JavaScript脚本的方法示例
Dec 31 Javascript
谈谈JavaScript中的函数与闭包
Apr 14 #Javascript
在新窗口打开超链接的方法小结
Apr 14 #Javascript
JS中setTimeout()的用法详解
Apr 14 #Javascript
js验证是否为数字的总结
Apr 14 #Javascript
JS 实现Json查询的方法实例
Apr 12 #Javascript
js弹出层(jQuery插件形式附带reLoad功能)
Apr 12 #Javascript
location对象的属性和方法应用(解析URL)
Apr 12 #Javascript
You might like
PHP中JSON的应用技巧
2015/10/10 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
php输出图像的方法实例分析
2017/02/16 PHP
关于flash遮盖div浮动层的解决方法
2010/07/17 Javascript
Javascript学习笔记-详解in运算符
2011/09/13 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
用Move.js配合创建CSS3动画的入门指引
2015/07/22 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
2015/08/31 Javascript
jquery实现select选择框内容左右移动代码分享
2015/11/21 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
2017/03/04 Javascript
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
深入了解Python数据类型之列表
2016/06/24 Python
python中正则表达式 re.findall 用法
2018/10/23 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
2019/08/13 Python
pytorch使用 to 进行类型转换方式
2020/01/08 Python
django admin管理工具自定义时间区间筛选器DateRangeFilter介绍
2020/05/19 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
奢华时尚的创新平台:Baltini
2020/10/03 全球购物
师范生自荐信
2013/10/27 职场文书
项目合作协议书
2014/04/16 职场文书
贸易跟单员英文求职信
2014/04/19 职场文书
工程售后服务方案
2014/06/08 职场文书
企业文化宣传标语
2014/06/09 职场文书
教师暑期培训感言
2014/08/15 职场文书
119消防日活动总结
2014/08/29 职场文书
解除租房协议书
2014/12/03 职场文书
求职自荐信范文(优秀篇)
2015/03/27 职场文书
2019交通安全宣传标语集锦!
2019/06/28 职场文书
助学金申请书该怎么写?
2019/07/16 职场文书
导游词之天津古文化街
2019/11/09 职场文书
导游词之无锡梅园
2019/11/28 职场文书
Python中的变量与常量
2021/11/11 Python