深入了解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在IE或Firefox下获取鼠标位置的代码
Dec 18 Javascript
菜鸟javascript基础整理1
Dec 06 Javascript
C#中TrimStart,TrimEnd,Trim在javascript上的实现
Jan 17 Javascript
js实现仿MSN带关闭功能的右下角弹窗代码
Sep 04 Javascript
JS实现来回出现文字的状态栏特效代码
Oct 31 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
Dec 31 Javascript
vue组件watch属性实例讲解
Nov 07 Javascript
基于js 字符串indexof与search方法的区别(详解)
Dec 04 Javascript
了解在JavaScript中将值转换为字符串的5种方法
Jun 06 Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 Javascript
Vue.js 实现地址管理页面思路详解(地址添加、编辑、删除和设置默认地址)
Dec 11 Javascript
JavaScript数组常用的增删改查与其他属性详解
Oct 13 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+mysql保存和输出文件
2006/10/09 PHP
关于PHP实现异步操作的研究
2013/02/03 PHP
PHP小教程之实现双向链表
2014/06/12 PHP
ThinkPHP之getField详解
2014/06/20 PHP
ThinkPHP上使用多说评论插件的方法
2014/10/31 PHP
php中关于长度计算容易混淆的问题分析
2016/05/27 PHP
PHP的Trait机制原理与用法分析
2019/10/18 PHP
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
jQuery判断密码强度实现思路及代码
2013/04/24 Javascript
js Array操作的最简短最容易理解方法
2013/12/09 Javascript
jQuery+css3实现Ajax点击后动态删除功能的方法
2015/08/10 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
2015/10/27 Javascript
JavaScript中定义类的方式详解
2016/01/07 Javascript
微信小程序 wxapp画布 canvas详细介绍
2016/10/31 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
Angular.js中控制器之间的传值详解
2017/04/24 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
Parcel.js + Vue 2.x 极速零配置打包体验教程
2017/12/24 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
Nodejs Express 通过log4js写日志到Logstash(ELK)
2018/08/30 NodeJs
js+canvas实现两张图片合并成一张图片的方法
2019/11/01 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
2020/01/21 Javascript
Vue强制组件重新渲染的方法讨论
2020/02/03 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
2020/10/29 Javascript
[50:04]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第二局
2016/02/28 DOTA
利用Python如何制作好玩的GIF动图详解
2018/07/11 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
浅谈Python中的生成器和迭代器
2020/06/19 Python
如何基于python把文字图片写入word文档
2020/07/31 Python
python中操作文件的模块的方法总结
2021/02/04 Python
html5理解head_动力节点Java学院整理
2017/07/13 HTML / CSS
亚马逊墨西哥站:Amazon.com.mx
2018/08/26 全球购物
C#面试题
2016/05/06 面试题
主要的Ajax框架都有什么
2013/11/14 面试题
前台领班岗位职责
2013/12/04 职场文书
医学院毕业生自荐信范文
2014/03/06 职场文书