深入了解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 相关文章推荐
Web层改进II-用xmlhttp 无声息提交复杂表单
Jan 22 Javascript
jquery下onpropertychange事件的绑定方法
Aug 01 Javascript
jquery中的on方法使用介绍
Dec 29 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
Mar 12 Javascript
js 显示base64编码的二进制流网页图片
Apr 04 Javascript
第一篇初识bootstrap
Jun 21 Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
Sep 26 Javascript
简单理解vue中实例属性vm.$els
Dec 01 Javascript
js 文字超出长度用省略号代替,鼠标悬停并以悬浮框显示实例
Dec 06 Javascript
Webpack框架核心概念(知识点整理)
Dec 22 Javascript
JavaScript图片处理与合成总结
Mar 04 Javascript
layui实现给某一列加点击事件
Oct 26 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
JS与PHP向函数传递可变参数的区别实例代码
2011/05/18 PHP
10款PHP开源商城系统汇总介绍
2015/07/23 PHP
php实现的单一入口应用程序实例分析
2015/09/23 PHP
PHP sdk文档处理常用代码示例解析
2020/12/09 PHP
解决jquery的.animate()函数在IE6下的问题
2010/12/03 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
2014/10/17 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
关于两个jQuery(js)特效冲突的bug的解决办法
2016/09/04 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
2017/07/13 jQuery
基于构造函数的五种继承方法小结
2017/07/27 Javascript
JS实现判断图片是否加载完成的方法分析
2018/07/31 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
ionic使用angularjs表单验证(模板验证)
2018/12/12 Javascript
layui表格内容溢出的解决方法
2019/09/06 Javascript
Vue 刷新当前路由的实现代码
2019/09/26 Javascript
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
Python使用matplotlib的pie函数绘制饼状图功能示例
2018/01/08 Python
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
将TensorFlow的模型网络导出为单个文件的方法
2018/04/23 Python
Python 实现自动导入缺失的库
2019/10/29 Python
python中必要的名词解释
2019/11/20 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
如何提高MySql的安全性
2014/06/19 面试题
工商管理系学生的自我评价分享
2013/11/29 职场文书
浙大毕业生自荐信
2014/01/26 职场文书
质量标语大全
2014/06/12 职场文书
家长会标语
2014/06/24 职场文书
教师节活动总结
2014/08/29 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
精神文明建设先进个人事迹材料
2014/12/24 职场文书
护士年终个人总结
2015/02/13 职场文书
公司优秀员工推荐信
2015/03/24 职场文书
被告代理词范文
2015/05/25 职场文书
运动员代表致辞
2015/07/29 职场文书
JS实现简单控制视频播放倍速的实例代码
2021/04/18 Javascript