深入了解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实现瀑布流效果(循环渐近)
Jan 27 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
Mar 11 Javascript
JavaScript 中 avalon绑定属性总结
Oct 19 Javascript
遍历json获得数据的几种方法小结
Jan 21 Javascript
JavaScript表单验证的两种实现方法
Feb 11 Javascript
微信小程序 参数传递实例代码
Mar 20 Javascript
React 高阶组件入门介绍
Jan 11 Javascript
js实现图片上传即时显示效果
Sep 30 Javascript
Vue实现兄弟组件间的联动效果
Jan 21 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
Feb 06 Javascript
Vue如何实现监听组件原生事件
Jul 03 Javascript
JS创建自定义对象的六种方法总结
Dec 15 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生成图片缩略图功能示例
2017/02/22 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
2017/11/14 PHP
gearman中任务的优先级和返回状态实例分析
2020/02/27 PHP
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
js数组去重的常用方法总结
2014/01/24 Javascript
JavaScript学习笔记之JS对象
2015/01/22 Javascript
深入探寻seajs的模块化与加载方式
2015/04/14 Javascript
angular.js之路由的选择方法
2016/09/24 Javascript
Javascript 闭包详解及实例代码
2016/11/30 Javascript
JavaScript数组去重的6个方法
2017/01/21 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
2017/05/10 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
js判断文件类型大小并给出提示的实现方法
2018/01/03 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
PHPStorm中如何对nodejs项目进行单元测试详解
2019/02/28 NodeJs
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
javascript 设计模式之享元模式原理与应用详解
2020/04/08 Javascript
详解JavaScript 异步编程
2020/07/13 Javascript
[02:33]DOTA2英雄基础教程 司夜刺客
2013/12/04 DOTA
python读取浮点数和读取文本文件示例
2014/05/06 Python
Python面向对象编程基础解析(二)
2017/10/26 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
2018/10/21 Python
在pycharm中使用git版本管理以及同步github的方法
2019/01/16 Python
基于python实现微信好友数据分析(简单)
2020/02/16 Python
Python 实现 T00ls 自动签到脚本代码(邮件+钉钉通知)
2020/07/06 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
什么是表空间(tablespace)和系统表空间(System tablespace)
2013/02/25 面试题
党校培训自我鉴定
2014/02/01 职场文书
消防宣传口号
2014/06/16 职场文书
森林防火宣传标语
2014/06/27 职场文书
党支部群众路线整改措施思想汇报
2014/10/10 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android
解析MySQL索引的作用
2022/03/03 MySQL