深入了解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中Math对象使用说明
Jan 16 Javascript
jQuery 源码分析笔记(5) jQuery.support
Jun 19 Javascript
延时加载JavaScript代码提高速度
Dec 27 Javascript
多种js图片预加载实现方式分享
Feb 19 Javascript
JS模拟bootstrap下拉菜单效果实例
Jun 17 Javascript
轻松搞定js表单验证
Oct 13 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
Mar 08 Javascript
javascript简单链式调用案例分析
May 10 Javascript
react中的ajax封装实例详解
Oct 17 Javascript
AngularJS监听ng-repeat渲染完成的两种方法
Jan 16 Javascript
微信小程序排坑指南详解
May 23 Javascript
小试小程序云开发(小结)
Jun 06 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在线打包程序源码
2008/07/27 PHP
PHP在不同页面间传递Json数据示例代码
2013/06/08 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
2007/02/05 Javascript
js停止输出代码
2008/07/20 Javascript
jquery实现多行文字图片滚动效果示例代码
2014/10/10 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
2015/02/03 Javascript
jQuery实现Meizu魅族官方网站的导航菜单效果
2015/09/14 Javascript
jQuery获取父元素节点、子元素节点及兄弟元素节点的方法
2016/04/14 Javascript
javascript将中国数字格式转换成欧式数字格式的简单实例
2016/08/02 Javascript
基于vue实现分页/翻页组件paginator示例
2017/03/09 Javascript
js 判断一个数字是不是2的n次方幂的实例
2017/11/26 Javascript
JavaScript实现微信号随机切换代码
2018/03/09 Javascript
node中的cookie的具体使用
2018/09/13 Javascript
JS实现的点击按钮图片上下滚动效果示例
2019/01/28 Javascript
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
Python单链表的简单实现方法
2014/09/23 Python
为Python的web框架编写前端模版的教程
2015/04/30 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
Django对数据库进行添加与更新的例子
2019/07/12 Python
详解如何用TensorFlow训练和识别/分类自定义图片
2019/08/05 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
俄罗斯香水在线商店:AromaCode
2019/12/04 全球购物
关于环保的演讲稿
2014/05/10 职场文书
行政文员岗位职责
2015/02/04 职场文书
2015年学生会个人工作总结
2015/04/09 职场文书
工伤劳动仲裁代理词
2015/05/25 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
实习员工转正的评语汇总,以备不时之需
2019/12/17 职场文书
Java并发编程之Executor接口的使用
2021/06/21 Java/Android
你需要掌握的20个Python常用技巧
2022/02/28 Python
Vue3中toRef与toRefs的区别
2022/03/24 Vue.js
使用Apache Camel表达REST服务的方法
2022/06/10 Servers
python+pyhyper实现识别图片中的车牌号思路详解
2022/12/24 Python