深入了解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代码
Nov 19 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
Feb 04 Javascript
浅谈使用MVC模式进行JavaScript程序开发
Nov 10 Javascript
js只执行1次的函数示例
Jul 20 Javascript
JavaScript每天必学之事件
Sep 18 Javascript
Angular4表单验证代码详解
Sep 03 Javascript
Bootstrap 树控件使用经验分享(图文解说)
Nov 06 Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
Sep 03 Javascript
浅谈vue加载优化策略
Mar 19 Javascript
Vue.js watch监视属性知识点总结
Nov 11 Javascript
使用JavaScript通过前端发送电子邮件
May 22 Javascript
vue实现户籍管理系统
May 29 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
《忧国的莫里亚蒂》先导宣传图与STAFF公开
2020/03/04 日漫
PHP常用技巧总结(附函数代码)
2012/02/04 PHP
CakePHP框架Model关联对象用法分析
2017/08/04 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
PHP中isset、empty的用法与区别示例详解
2020/11/05 PHP
Javascript中的方法链(Method Chaining)介绍
2015/03/15 Javascript
提升jQuery的性能需要做好七件事
2016/01/11 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
2016/12/08 Javascript
nodejs进阶(6)—连接MySQL数据库示例
2017/01/07 NodeJs
JS 插件dropload下拉刷新、上拉加载使用小结
2017/04/13 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
解决vue+element 键盘回车事件导致页面刷新的问题
2018/08/25 Javascript
jQuery简单实现根据日期计算星期几的方法
2019/01/09 jQuery
Vue数组响应式操作及高阶函数使用代码详解
2020/08/01 Javascript
Python抓取电影天堂电影信息的代码
2016/04/07 Python
python实现内存监控系统
2021/03/07 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
PyTorch里面的torch.nn.Parameter()详解
2020/01/03 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
Python实现石头剪刀布游戏
2021/01/20 Python
美国最大的珠宝商之一:Littman Jewelers
2016/11/13 全球购物
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
Ever New加拿大官网:彰显女性美
2018/10/05 全球购物
Edwaybuy西班牙:小米在线商店
2019/12/04 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
【魔兽争霸3重制版】原版画面与淬火MOD画面对比
2021/03/26 魔兽争霸
仓管员岗位职责范文
2013/11/08 职场文书
餐饮管理自我介绍信
2014/01/15 职场文书
协商一致解除劳动合同协议书
2014/09/14 职场文书
个人四风问题原因分析及整改措施
2014/09/28 职场文书
搬迁通知
2015/04/20 职场文书
转学证明范本
2015/06/19 职场文书
小型婚礼主持词
2015/06/30 职场文书
解决Swagger2返回map复杂结构不能解析的问题
2021/07/02 Java/Android