博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript之深入浅出prototype
阅读量:4932 次
发布时间:2019-06-11

本文共 2326 字,大约阅读时间需要 7 分钟。

 

  我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在js里我们就把这个池塘称为原型对象,池塘里面我们所共享的鱼称为原型中的属性及方法,而我们自己的鱼称为构造函数中的属性及方法,我们是什么呢?对了,我们是对象的实例。 

  以上是为了让大家能够趣味性的对prototype有一个概念,接下来就通过代码具体总结一下prototype~

一、理解prototype

  我们创建的每一个函数都有一个prototype属性,这个属性是一个指向对象的指针。

  构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。以下是用原型模式创建的一个对象:

1 function person(name, age) { 2   this.name = name; 3   this.age = age; 4 } 5 person.prototype = { 6   sayName: function() { 7     console.log(this.name);       8   } 9 };10 11 var p1 = new person("Wind", 20);12 p1.sayName(); // "Wind"13 14 var p2 = new person("Nic", 20);15 p2.sayName(); // Nic

  这里我将name、age属性定义在构造函数中,将sayName方法定义在原型中。所以p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。

  试想如果我们不用prototype,而是直接将sayName写进构造函数呢?

  那么p1和p2中将各有一份sayName,这样浪费内存空间,所以用prototype的好处之一:提高了代码的复用性,减少内存。

  在了解原型对象的同时我们还有一个小知识要明白:每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:

    对象实例本身---->原型对象---->对象所继承的父类对象---->父类对象原型...---->原型链末端

 

二、prototype的注意点

1、不可变性:尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如数组)

基本类型:

1 function person() {} 5 person.prototype = {  6    num: 0 7 };   8 var p1 = new person();  9 var p2 = new person();10 p1.num++;11 p2.num; // 0

非基本类型:

1 function person() {} 5 person.prototype = { 6    num: [1,2,3] 7 };   8 var p1 = new person();  9 var p2 = new person();10 p1.num[2] = 8; 11 p2.num; //  [1, 2, 8]  改变了

 

2、同名覆盖性:如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。

1 function person(name) { 2   this.name = name;  3 } 4 person.prototype = { 5    age: 18  6 }; 7 var p1 = new person("Wind"); 8 var p2 = new person("Nic"); 9 p1.age = 20;10 p1.age; // 2011 p2.age; // 18

 

3、使用对象字面量创建原型方法,会切断之前的链而重写原型链

1 function person(name) { 2   this.name = name;  3 } 4 person.prototype = {  5   sayName: function() { 6     console.log(this.name);       7   } 8 }; 9 var p1 = new person("Wind");10 11 person.prototype = {12   age : 2013 }; 14 p1.sayName();  // Wind15 p1.age; // undefined16 17 var p2 = new person("Nic");18 p2.sayName();  // error19 p2.age;  // 20

  因为prototype指针指向了一个新的对象,切断了构造函数与之前的prototype旧对象的联系,然而p1的prototype指针指向的依旧是旧对象。而新创建的实例p2指向的prototype新对象。

 

三、总结

  prototype的用法:构造函数模型用于定义实例的属性,而原型模型用于定义方法和共享的属性。

转载于:https://www.cnblogs.com/alinaxia/p/6372266.html

你可能感兴趣的文章
C++成员函数的重载、覆盖与隐藏【转载】
查看>>
网站开发技能图谱
查看>>
4.27随笔
查看>>
CSS实例:图片导航块
查看>>
poj1860 Currency Exchange(spfa判断正环)
查看>>
SQL CHECK 约束&Case when 的使用方法
查看>>
[整理]HTTPS和SSL证书
查看>>
[转载] Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
查看>>
UVA12206 Stammering Aliens 【SAM 或 二分 + hash】
查看>>
水晶苍蝇拍:聊聊估值那些事儿——“指标”背后的故事 (2011-11-01 14:58:32)
查看>>
3.每周总结
查看>>
应用提交 App Store 上架被拒绝
查看>>
Android实现异步处理 -- HTTP请求
查看>>
数据清空js清空div里的数据问题
查看>>
Fortran中的指针使用
查看>>
移动终端app测试点总结
查看>>
14-6-27&28自学内容小结
查看>>
JSP
查看>>
---
查看>>
(第一组_GNS3)自反ACl
查看>>