深入了解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 相关文章推荐
JS的IE和Firefox兼容性集锦
Dec 11 Javascript
JavaScript 基础知识 被自己遗忘的
Oct 15 Javascript
Javascript的构造函数和constructor属性
Jan 09 Javascript
jquery对元素拖动排序示例
Jan 16 Javascript
jquery map方法使用示例
Apr 23 Javascript
jQuery获取节点和子节点文本的方法
Jul 22 Javascript
form.submit()不能提交表单的错误原因及解决方法
Oct 13 Javascript
JS中Location使用详解
May 12 Javascript
js事件冒泡、事件捕获和阻止默认事件详解
Aug 04 Javascript
详解Node.js:events事件模块
Nov 24 Javascript
让你彻底掌握es6 Promise的八段代码
Jul 26 Javascript
mpvue 项目初始化及实现授权登录的实现方法
Jul 20 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
Discuz 5.0 中读取纯真IP数据库函数分析
2007/03/16 PHP
PHP array操作10个小技巧分享
2011/06/23 PHP
老生常谈文本文件和二进制文件的区别
2017/02/27 PHP
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
2012/05/30 Javascript
js获取class的所有元素
2013/03/28 Javascript
深入理解javascript动态插入技术
2013/11/12 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
jQuery预加载图片常用方法
2015/06/15 Javascript
兼容各大浏览器的JavaScript阻止事件冒泡代码
2015/07/09 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
你不需要jQuery(三) 新AJAX方法fetch()
2016/06/14 Javascript
JS只能输入正整数的简单实例
2016/10/07 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
2016/10/18 Javascript
ES6新特性之类(Class)和继承(Extends)相关概念与用法分析
2017/05/24 Javascript
javaScript手机号码校验工具类PhoneUtils详解
2017/12/08 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
JavaScript中CreateTextFile函数
2020/08/30 Javascript
vue 封装面包屑组件教程
2020/11/16 Javascript
Python和C/C++交互的几种方法总结
2017/05/11 Python
Python使用time模块实现指定时间触发器示例
2017/05/18 Python
Python装饰器基础概念与用法详解
2018/12/22 Python
pandas DataFrame 交集并集补集的实现
2019/06/24 Python
使用python的pyplot绘制函数实例
2020/02/13 Python
python matplotlib:plt.scatter() 大小和颜色参数详解
2020/04/14 Python
sleep()方法和wait()方法的区别是什么
2012/11/17 面试题
KTV的创业计划书范文
2014/02/02 职场文书
施工工地安全标语
2014/06/07 职场文书
活动总结报告怎么写
2014/07/03 职场文书
2014年驾驶员工作总结
2014/11/18 职场文书
一年级数学下册复习计划
2015/01/17 职场文书
2015年创先争优活动总结
2015/03/27 职场文书
大学生,三分钟即兴演讲稿
2019/07/22 职场文书
晶体管来复再生式二管收音机
2021/04/22 无线电
Nginx下SSL证书安装部署步骤介绍
2021/12/06 Servers
MySql数据库触发器使用教程
2022/06/01 MySQL