深入了解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 相关文章推荐
jQuery实现的立体文字渐变效果
May 17 Javascript
Jquery常用技巧收集整理篇
Nov 14 Javascript
也说JavaScript中String类的replace函数
Sep 22 Javascript
javascript if条件判断方法小结
May 17 Javascript
javascript定义变量时有var和没有var的区别探讨
Jul 21 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
Oct 22 Javascript
javascript实现省市区三级联动下拉框菜单
Nov 17 Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 Javascript
js实现3d悬浮效果
Feb 16 Javascript
详解使用angular-cli发布i18n多国语言Angular应用
May 20 Javascript
vue源码解析之事件机制原理
Apr 21 Javascript
vue实现的仿淘宝购物车功能详解
Jan 27 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 daddslashes 使用方法介绍
2012/10/26 PHP
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
腾讯CMEM的PHP扩展编译安装方法
2015/09/25 PHP
php 数组元素快速去重
2017/05/05 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
2019/05/13 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
JavaScript去掉空格的方法集合
2010/12/28 Javascript
jquery动态加载图片数据练习代码
2011/08/04 Javascript
js设置cookie过期及清除浏览器对应名称的cookie
2013/10/24 Javascript
escape函数解决js中ajax传递中文出现乱码问题
2014/10/30 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
原生JS实现拖拽图片效果
2020/08/27 Javascript
mvvm双向绑定机制的原理和实现代码(推荐)
2016/06/07 Javascript
微信小程序  简单实例(阅读器)的实例开发
2016/09/29 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
2016/12/15 Javascript
把JavaScript代码改成ES6语法不完全指南(分享)
2017/09/10 Javascript
JavaScript requestAnimationFrame动画详解
2017/09/14 Javascript
JS+HTML+CSS实现轮播效果
2017/11/28 Javascript
vue.js删除列表中的一行
2018/06/30 Javascript
JS+CSS3实现的简易钟表效果示例
2019/04/13 Javascript
vue通过数据过滤实现表格合并
2020/11/30 Javascript
layui给下拉框、按钮状态、时间赋初始值的方法
2019/09/10 Javascript
layui扩展上传组件模拟进度条的方法
2019/09/23 Javascript
javascript操作元素的常见方法小结
2019/11/13 Javascript
JavaScript通如何过RGraph实现动态仪表盘
2020/10/15 Javascript
vue3+typescript实现图片懒加载插件
2020/10/26 Javascript
通过vue.extend实现消息提示弹框的方法记录
2021/01/07 Vue.js
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
python实现将读入的多维list转为一维list的方法
2018/06/28 Python
对pyqt5中QTabWidget的相关操作详解
2019/06/21 Python
python中plt.imshow与cv2.imshow显示颜色问题
2020/07/16 Python
python mock测试的示例
2020/10/19 Python
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
关于抽烟的检讨书
2014/02/25 职场文书
聘任合同书
2015/09/21 职场文书