Javascript之深入浅出prototype

Javascript之深入浅出prototype

我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在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; // 20
11 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 : 20
13 };
14 p1.sayName();  // Wind
15 p1.age; // undefined
16
17 var p2 = new person("Nic");
18 p2.sayName();  // error
19 p2.age;  // 20

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

三、总结

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

时间: 2024-08-27 22:52:10

Javascript之深入浅出prototype的相关文章

JavaScript中Object.prototype.toString方法的原理

在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. ? 1 2 var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]" 本文要讲的就是,toString方法是如何做到这一点的,原理是什么. ECMAScript 3 在ES3中,Object.prototype.toString方法的规范如下:

Javascript对象的prototype

转帖: http://www.alloyteam.com/2015/10/prototype/?hmsr=toutiao.io&bsh_bid=928776428 最近恰好有人问起关于 javascript 中的 prototype 相关的问题.特此简单地整理了一下,比较基础,希望能让有类型问题的同学,可以用这篇文章提供参考. prototype 是通过调用构造函数而创建的对象实例的原型对象. 每一个新的函数,都会拥有一个 prototype 属性,这个属性指向函数的原型对象. 所有原型对象都有

理解javascript中的prototype

以前一直对javascript中的prototype不是很理解,今天在阅读了<javascript高级程序设计之后>终于理解了其中的prototype.来简单的总结一下从书中学习到的内容. 我们都知道在创建了一个function之后,这个function就具有了prototype这样的一个属性,利用这个prototype我们可以做很多的事情,其中我们经常用到的一点就是利用它来当做构造函数,因此,本文重要从function作为构造函数的角度来说明一下prototype. 其实javascript

JavaScript强化教程——Prototype

本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 -- Prototype 引用 Prototype 如需测试 JavaScript 库,您需要在网页中引用它. 为了引用某个库,请使用 <script> 标签,其 src 属性设置为库的 URL: 引用 Prototype <!DOCTYPE html> <html> <head> <script src="http://apps.bdimg.com/

Javascript属性constructor/prototype的底层原理

在Javascript语言中,constructor属性是专门为function而设计的,它存在于每一个function的prototype属性中.这个constructor保存了指向function的一个引用.在定义一个函数(代码如下所示)时, function F() { // some code } JavaScript内部会执行如下几个动作: 为该函数添加一个原形属性(即prototype对象). 为prototype对象额外添加一个constructor属性,并且该属性保存指向函数F的

JavaScript中的prototype和__proto__细致解析

最近在学js,体会了一点点它的灵活性.对于初学者的我,总是被它的灵活感到晕头转向,最近发现了一点东西想与大家分享. JavaScript中的prototype和_proto_: 我们先了解一点js中的基础知识,首先我们先看一段js代码: 1 var object = new Object; 2 console.log("object:", object); 3 object.member1 = "abcd"; 4 5 var obj = {}; 6 obj.memb

JavaScript中的prototype

关于prototype: 理解prototype不应把它和继承混淆.A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍.A能使用B的方法和属性.这里强调的是克隆而不是继承.可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例. 现在有一个类A,我想要创建一个类B,我希望这个B类能够继承A类的方法和属性,并且能进行扩展(即添加额外的方法和属性).那么我们称B的原型为A.即为:B.prototype = A javascript的方

对于JavaScript对象的prototype和__proto__的理解

一.Object和Function的关系: 刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象.瞬间觉得Object碉堡了! 后来,又认识了Function,才知道原来Function才是隐藏在幕后的大BOSS,Object只不过是个大师兄. Object和Function都是JS自带的函数对象,Function比较牛逼点,因为它是Object的构造函数,而且Object的__proto__属性指向

javascript Array对象prototype属性

prototype 属性使您有能力向对象添加属性和方法. 语法: object.prototype.name=value 例子: <script type="text/javascript"> function employee(name,job,born) { this.name=name; this.job=job; this.born=born; } var bill=new employee("Bill Gates","Engineer