深入了解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文字滚动停顿效果代码
Jun 28 Javascript
js获取TreeView控件选中节点的Text和Value值的方法
Nov 24 Javascript
jQuery基本过滤选择器使用介绍
Apr 18 Javascript
Javascript中的for in循环和hasOwnProperty结合使用
Jun 05 Javascript
jQuery中hover与mouseover和mouseout的区别分析
Dec 24 Javascript
jQuery实现鼠标选文字发新浪微博的方法
Apr 02 Javascript
JQuery点击事件回到页面顶部效果的实现代码
May 24 Javascript
JavaScript来实现打开链接页面的简单实例
Jun 02 Javascript
创建一般js对象的几种方式
Jan 19 Javascript
详解webpack2+React 实例demo
Sep 11 Javascript
浅谈vue.use()方法从源码到使用
May 12 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
Aug 10 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
使用MaxMind 根据IP地址对访问者定位
2006/10/09 PHP
php学习之数据类型之间的转换介绍
2011/06/09 PHP
php从数组中随机选择若干不重复元素的方法
2015/03/14 PHP
Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
2019/08/02 PHP
JS简单实现登陆验证附效果图
2013/11/19 Javascript
JavaScript中操作Mysql数据库实例
2015/04/02 Javascript
JavaScript实现选择框按比例拖拉缩放的方法
2015/08/04 Javascript
jQuery多条件筛选如何实现
2015/11/04 Javascript
解析javascript瀑布流原理实现图片滚动加载
2016/03/10 Javascript
input 禁止输入特殊字符的四种实现方式
2016/08/24 Javascript
Vue.js实现无限加载与分页功能开发
2016/11/03 Javascript
Sequelize中用group by进行分组聚合查询
2016/12/12 Javascript
JS兼容所有浏览器的DOMContentLoaded事件
2018/01/12 Javascript
element ui里dialog关闭后清除验证条件方法
2018/02/26 Javascript
jQuery阻止事件冒泡实例分析
2018/07/03 jQuery
浅谈让你的代码更简短,更整洁,更易读的ES6小技巧
2018/10/25 Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
2018/12/20 Javascript
详解Typescript里的This的使用方法
2021/01/08 Javascript
Python采用socket模拟TCP通讯的实现方法
2014/11/19 Python
Python Matplotlib库入门指南
2015/05/18 Python
Python实现数据库编程方法详解
2015/06/09 Python
python编程通过蒙特卡洛法计算定积分详解
2017/12/13 Python
让Django支持Sql Server作后端数据库的方法
2018/05/29 Python
利用Python如何实现一个小说网站雏形
2018/11/23 Python
python 获取url中的参数列表实例
2018/12/18 Python
selenium获取当前页面的url、源码、title的方法
2019/06/12 Python
python pip如何手动安装二进制包
2020/09/30 Python
python request 模块详细介绍
2020/11/10 Python
澳大利亚和新西兰最大的在线旅行社之一:Aunt Betty
2019/08/07 全球购物
员工试用期自我鉴定范文
2014/09/15 职场文书
小学生成绩单评语
2014/12/31 职场文书
幼儿园小班教学反思
2016/03/03 职场文书
个人销售励志奋斗口号
2019/12/05 职场文书
详细分析PHP7与PHP5区别
2021/06/26 PHP
vue3.0 数字翻牌组件的使用方法详解
2022/04/20 Vue.js
CSS 左边固定宽右边自适应的6种方法
2022/05/15 HTML / CSS