时间:2021-05-26
我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在js里我们就把这个池塘称为原型对象,池塘里面我们所共享的鱼称为原型中的属性及方法,而我们自己的鱼称为构造函数中的属性及方法,我们是什么呢?对了,我们是对象的实例。
以上是为了让大家能够趣味性的对prototype有一个概念,接下来就通过代码具体总结一下prototype~
一、理解prototype
我们创建的每一个函数都有一个prototype属性,这个属性是一个指向对象的指针。
构建对象中有一种模式叫做原型模式,意思是将对象实例所不可共享的属性及方法定义在构造函数中,而将可共享的属性及方法放在原型对象中,也就是prototype指向的对象中。以下是用原型模式创建的一个对象:
function person(name, age) { this.name = name; this.age = age;}person.prototype = { sayName: function() { console.log(this.name); }};var p1 = new person("Wind", 20);p1.sayName(); // "Wind"var p2 = new person("Nic", 20);p2.sayName(); // Nic这里我将name、age属性定义在构造函数中,将sayName方法定义在原型中。所以p1和p2对象实例的内存空间里面各有一份name和age,但是它们却共享一份sayName方法,意思是它们调用的sayName方法是同一个。
试想如果我们不用prototype,而是直接将sayName写进构造函数呢?
那么p1和p2中将各有一份sayName,这样浪费内存空间,所以用prototype的好处之一:提高了代码的复用性,减少内存。
在了解原型对象的同时我们还有一个小知识要明白:每当代码读取一个对象属性的时候会执行一次搜索,搜索目标是给定名字的属性,搜索路径为:
对象实例本身---->原型对象---->对象所继承的父类对象---->父类对象原型...---->原型链末端
二、prototype的注意点
1、不可变性:尽管prototype是共享的,但不能通过对象实例重写原型中的值,但是可以由对象统一改。通俗一点:只能爸爸统一改,不能儿子改。(这也和类型有关系,孩子不能改变基本类型的值,但是可以改变对象,比如数组)
基本类型:
function person() {}person.prototype = { num: 0}; var p1 = new person(); var p2 = new person();p1.num++;p2.num; // 0非基本类型:
function person() {}person.prototype = { num: [1,2,3]}; var p1 = new person(); var p2 = new person();p1.num[2] = 8; p2.num; // [1, 2, 8] 改变了2、同名覆盖性:如果我们在实例中添加了一个与原型属性同名的属性,那么该属性会创建到对象实例中并且会覆盖掉原型中的相应属性。
function person(name) { this.name = name; }person.prototype = { age: 18 9 };var p1 = new person("Wind");var p2 = new person("Nic");p1.age = 20;p1.age; // 20p2.age; // 183、使用对象字面量创建原型方法,会切断之前的链而重写原型链
function person(name) { this.name = name; }person.prototype = { sayName: function() { console.log(this.name); }};var p1 = new person("Wind");person.prototype = { age = 20}; p1.sayName(); // error因为prototype指针指向了一个新的对象,切断了构造函数与之前的prototype旧对象的联系,所以p1不能调用了它。那么p1调用新对象的属性呢?
p1.age; // error
所以我做了一个大胆的猜测,就是以前包含sayName的旧对象被“抛弃”了,也就是被内存回收了,然而p1的prototype指针指向的依旧是旧对象,所以会产生error。
三、总结
prototype的用法:构造函数模型用于定义实例的属性,而原型模型用于定义方法和共享的属性。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
xml文件结构:books.xml深入浅出extjs张三88锋利的jQuery李四99深入浅出flex王五108java编程思想钱七128页面代码:jquery
学习资料 1.深入浅出Node.js 2.Node.js开发指南简介(只捡了我觉得重要的)Node.js是让Javascript脱离浏览器运行在服务器的一个
本文实例实现一下RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出。复习ListView可以查看这篇文章深入浅出学习AndroidListV
本文深入浅出的分析了ASP.NET深度复制和浅度复制。分享给大家供大家参考。具体分析如下:之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东
1、深入浅出,呈现给人以简单凝练之美。 做标志设计其实更多是考验设计师的视觉观察力和思维表现力。很多时候,标志设计甚至不需要标题或品牌的名称。因其具备足够