深入了解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焦点图切换特效插件封装实例
Aug 18 Javascript
JS 屏蔽按键效果与改变按键效果的示例代码
Dec 24 Javascript
javascript的解析执行顺序在各个浏览器中的不同
Mar 17 Javascript
JS显示表格内指定行html代码的方法
Mar 31 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
Aug 17 Javascript
详解javascript获取url信息的常见方法
Dec 19 Javascript
BootStrap 页签切换失效的解决方法
Aug 17 Javascript
利用纯js + transition动画实现移动端web轮播图详解
Sep 10 Javascript
jQuery实现的页面弹幕效果【测试可用】
Aug 17 jQuery
angular4中引入echarts的方法示例
Jan 29 Javascript
微信小程序new Date()方法失效问题解决方法
Jul 29 Javascript
uni app仿微信顶部导航条功能
Sep 17 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使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
Yii中render和renderPartial的区别
2014/09/03 PHP
CentOS系统中PHP安装扩展的方式汇总
2017/04/09 PHP
PHP使用xpath解析XML的方法详解
2017/05/20 PHP
php的扩展写法总结
2019/05/14 PHP
laravel 解决ajax异步提交数据,并还回填充表格的问题
2019/10/15 PHP
PHP扩展安装方法步骤解析
2020/11/24 PHP
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
ff下JQuery无法监听input的keyup事件的解决方法
2013/12/12 Javascript
jQuery旋转木马式幻灯片轮播特效
2015/12/04 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
微信小程序开发一键登录 获取session_key和openid实例
2016/11/23 Javascript
js中动态创建json,动态为json添加属性、属性值的实例
2016/12/02 Javascript
vue.js国际化 vue-i18n插件的使用详解
2017/07/07 Javascript
微信小程序调用微信支付接口的实现方法
2019/04/29 Javascript
微信小程序反编译的实现
2020/12/10 Javascript
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
python遍历类中所有成员的方法
2015/03/18 Python
python随机生成指定长度密码的方法
2015/04/04 Python
Python 中 list 的各项操作技巧
2017/04/13 Python
python微信公众号开发简单流程
2018/03/23 Python
numpy.delete删除一列或多列的方法
2018/04/03 Python
python画图系列之个性化显示x轴区段文字的实例
2018/12/13 Python
如何在Python中实现goto语句的方法
2019/05/18 Python
使用Python实现跳一跳自动跳跃功能
2019/07/10 Python
Python中url标签使用知识点总结
2020/01/16 Python
详解css3使用transform出现字体模糊的解决办法
2020/10/16 HTML / CSS
服务员岗位责任制
2014/02/11 职场文书
青春无悔演讲稿
2014/05/08 职场文书
港澳通行证委托书怎么写
2014/08/02 职场文书
JavaScript原始值与包装对象的详细介绍
2021/05/11 Javascript
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers
利用Python多线程实现图片下载器
2022/03/25 Python