我们先来讲一个故事,一个大大的池塘,里面有很多鱼。这是属于我们大家的池塘所以里面的鱼我们都可以吃,但是我们也会从集市买一些鱼放在家里,那么放在家里的鱼肯定是属于我们私人的,外人是不会拥有的。那么在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; //

非基本类型:

 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
};
var p1 = new person("Wind");
var p2 = new person("Nic");
p1.age = 20;
p1.age; //
p2.age; // 18

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

 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(); // Wind
p1.age; // undefined var p2 = new person("Nic");
p2.sayName(); // error
p2.age; //

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

三、总结

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

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

  1. 悟透Javascript之 原型prototype

    构造函数的Prototype上定义的方法确实可以通过对象直接调用,而且代码是共享的.我表示我不懂.太难理解了,艹.在Javascript中,prototype不但能让对象共享自己的财富,而且proto ...

  2. JavaScript -- 原型:prototype的使用

    JavaScript -- 原型:prototype的使用 在 JavaScript 中,prototype 是函数的一个属性,同时也是由构造函数创建的对象的一个属性. 函数的原型为对象. 它主要在函 ...

  3. JavaScript中的prototype和__proto__细致解析

    最近在学js,体会了一点点它的灵活性.对于初学者的我,总是被它的灵活感到晕头转向,最近发现了一点东西想与大家分享. JavaScript中的prototype和_proto_: 我们先了解一点js中的 ...

  4. javascript constrator and prototype

    揭开js之constructor属性的神秘面纱 在js里面当new了一个对象时,这中间发生了什么? MDN - new运算符 当代码 new foo(...) 执行时: 一个新对象被创建.它继承自fo ...

  5. C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数

    C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...

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

    在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. ? 1 2 var arr = []; console.lo ...

  7. javascript里的prototype

    在javascript中,prototype是函数的一个固有属性,其他对象,比如字符串什么的,并没有这个属性. 这个属性做什么用呢? 1.用于该函数的所有实例进行共享 比如,共同的属性,共同的方法.类 ...

  8. JavaScript原型链:prototype与__proto__

    title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...

  9. 谈谈javascript中的prototype与继承

    谈谈javascript中的prototype与继承 今天想谈谈javascript中的prototype. 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性 ...

随机推荐

  1. python数据类型之 dict(map)

    字典  一.创建字典  方法①:  >>> dict1 = {}  >>> dict2 = {'name': 'earth', 'port': 80}  >& ...

  2. Memcache第一篇---基础教程

    Memcache是什么 Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力. 它可以应 ...

  3. JVM线程安全

    一.线程的调度方式 线程调度分为两种方式: 协同式调度和抢占式调度.协同式调度:线程的执行时间由线程本身控制,线程将工作执行完之后,通知操作系统切换到其他线程上.缺点:时间不可控,就算出问题,也不会通 ...

  4. TFS-Git官方教程

    VS2015:官网教程 VS2013:  GIT教程

  5. 信息指纹(Fingerprint)及其应用

    1.应用:      i.网页地址去重           网页地址有100个字符,存储5000亿个网址本身需要50T的容量,而Hash表的存储效率只有50%,所有存储爬虫已经爬过的网址需要100T的 ...

  6. Vim配置C++

    当前用户的Vim配置便存储在文件 ~/.vimrc 中,该文件的每一行便是一个配置项 设置自动换行,在配置文件中加入如下代码: syntax onset tabstop=4set softtabsto ...

  7. springmvc的jdbcTemplate 插入 返回主键

    public int insertCustomer(final Customer customer) {        //TODO.        final String sql = " ...

  8. [Angular Tutorial] 11 -Custom Filters

    在这一步中您将学到如何创建您自己的展示过滤器. ·在先前的步骤中,细节页面展示“true”或“false”来显示某部电话是否有某项功能.在这一步中,我们将使用自定义的过滤器来将这些个字符串转化成符号: ...

  9. 如何在Eclipse下安装myeclipse插件

    来自http://www.blogjava.net/show911/archive/2008/04/27/86284.html 下载myeclipse插件 支持eclipse3.1.x, 具体安装步骤 ...

  10. 黄聪:VPS用轻松备份工具备份Wordpress,文件夹通配符

    db;log;wp-admin;wp-includes;temp;upgrade;twentyfourteen;twentyfifteen;twentysixteen;twentythirteen;t ...