深入了解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 读取XML数据,在页面中展现、编辑、保存的实现
Oct 27 Javascript
基于JQuery模仿苹果桌面的Dock效果(初级版)
Oct 15 Javascript
基于JQuery的模拟苹果桌面Dock效果(稳定版)
Oct 15 Javascript
node.js [superAgent] 请求使用示例
Mar 13 Javascript
jquery滚动到顶部底部代码
Apr 20 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
Jul 01 Javascript
JavaScript如何自定义trim方法
Jul 28 Javascript
jQuery图片加载显示loading效果
Nov 04 Javascript
Bootstrap CSS布局之表格
Dec 17 Javascript
原生js实现打字动画游戏
Feb 04 Javascript
vue.js 中使用(...)运算符报错的解决方法
Aug 09 Javascript
js实现web调用摄像头 js截取视频画面
Apr 21 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基础知识:类与对象(2) 自动加载对象
2006/12/13 PHP
php 结果集的分页实现代码
2009/03/10 PHP
关于ob_get_contents(),ob_end_clean(),ob_start(),的具体用法详解
2013/06/24 PHP
php设置静态内容缓存时间的方法
2014/12/01 PHP
PHP连接MySQL数据的操作要点
2015/03/20 PHP
初识ThinkPHP控制器
2016/04/07 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
PHP实现微信申请退款功能
2018/10/01 PHP
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
2013/04/15 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
原生JS实现响应式瀑布流布局
2015/04/02 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
2016/08/16 NodeJs
BooStrap对导航条的改造实践小结
2016/09/21 Javascript
Vue.js实现微信过渡动画左右切换效果
2017/06/13 Javascript
JS实现的走迷宫小游戏完整实例
2017/07/19 Javascript
解决vue+element 键盘回车事件导致页面刷新的问题
2018/08/25 Javascript
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
2018/10/12 Javascript
js实现指定时间倒计时效果
2019/08/26 Javascript
微信小程序用户盒子、宫格列表的实现
2020/07/01 Javascript
[06:24]DOTA2 2015国际邀请赛中国区预选赛第二日TOP10
2015/05/27 DOTA
Python字符串处理函数简明总结
2015/04/13 Python
Python中subprocess模块用法实例详解
2015/05/20 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
2018/04/27 Python
用TensorFlow实现戴明回归算法的示例
2018/05/02 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
python调用自定义函数的实例操作
2019/06/26 Python
Python封装成可带参数的EXE安装包实例
2019/08/24 Python
解决img标签上下出现间隙的方法
2016/12/14 HTML / CSS
巴西24小时在线药房:Droga Raia
2020/05/12 全球购物
社区优秀志愿者材料
2014/02/02 职场文书
机关党员四风问题个人整改措施
2014/10/26 职场文书
python3美化表格数据输出结果的实现代码
2021/04/14 Python
CSS3实现360度循环旋转功能
2022/02/12 HTML / CSS
MySQL批量更新不同表中的数据
2022/05/11 MySQL
Win10本地连接不见了怎么恢复? win10系统电脑本地连接不见了解决方法
2023/01/09 数码科技