一个有关原型的问题牵扯出的问题

最近推荐一个朋友学习js,今天他问了我一个问题,问题如下:

 1 function Box (){}
 2 Box.prototype = {
 3     name : ‘Lee‘,
 4     age : 28,
 5     run : function (){
 6         return this.name+this.age+‘运行中...‘;
 7     }
 8 };
 9 var box = new Box();
10 Box.prototype = {
11     age : 200
12 };
13 alert(box.age);

这里alert出来的结果是多少呢?结果是28,他问我为什么是28,我运行代码之后发现是28,但是我也没有想明白为什么是。虽然一直使用js,但是每次遇到原型这个地方的问题的时候我还是会蒙,一直对这个理解的不是很透彻。刚好借着这个问题,我详细的看了下书和资料,算是弄明白了为什么。

这里先引用一段JavaScript高级程序设计(第三版)中的一段话。

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。

这里有点抽象,我借用书中一个图说明下:

这里可以看出Box.prototype.constructor == Box;

上面的问题在哪里呢?当Box.prototype = {};一个新的对象的时候,这段代码:

1 function Box (){}
2 Box.prototype = {
3     name : ‘Lee‘,
4     age : 28,
5     run : function (){
6         return this.name+this.age+‘运行中...‘;
7     }
8 };

这段之后,这个Box.prototype.constructor == Box;就不成立了,

其实上面说的这段没啥用,只是为了凑字数显得字多,而接下来的new这个操作才是真正的起了作用。这里要理解new这个操作到底做了什么,在理解之前,先插入一段书上的原话:

创建了自定义的构造函数之后,其原型对象默认只会去的constructor属性,至于其他方法,则都是从Object继承而来的。当调用构造函数创建一个新实例后,该实例内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262第五版中管这个指针叫[[Prototype]]。虽然在脚本中没有标准的方式访问[[Prototype]]。但Firefox, Safari和Chrome在每个对象上都支持一个属性__proto__;而在其他实现中,这个属性对脚本则是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。

几把越看越晕了,看代码就好了:

1 var box = new Box();
2 // function new () {
3 //     var box = {};
4 //     box.__proto__ = Box.prototype;
5 //     Box.apply(box, arguments);
6 //       return box;
7 // }
8 注释部分只是方便理解

如果这样的话,上面的问题就一下子晴朗了,因为在new的时候指定了box内部__proto__的指向,这个指向就是Box.prototype的指向,

为了方便理解我把代码修改成如下:

 1 function Box (){}
 2
 3 console.log(Box.prototype.constructor == Box);    //true
 4
 5 var obj1 = {
 6     name : ‘Lee‘,
 7     age : 28,
 8     run : function (){
 9         return this.name+this.age+‘运行中...‘;
10     }
11 };
12
13 Box.prototype = obj1;
14
15 var box = new Box();
16 // function new () {
17 //     var box = {};
18 //     box.__proto__ = Box.prototype;
19 //     Box.apply(box, arguments);
20 //       return box;
21 // }
22
23 console.log(box.age);
24
25
26 var obj2 = {
27     age : 200
28 };
29
30 Box.prototype = obj2;
31
32 console.log(Box.prototype.isPrototypeOf(box));               //false
33 console.log(Object.getPrototypeOf(box) == Box.prototype);    //false
34 console.log(Object.getPrototypeOf(box) == obj1);             //true
35 console.log(Object.getPrototypeOf(box) == obj2);             //false
36
37 console.log(box.age);

因为已经new过了,而new过之后修改Box.prototype又是直接给了一个新的对象obj2, 所以原来的box内部的__proto__还是指向obj1, 跟Box没关系,只是Box.prototype是指向obj2而已。

一个小小的问题让我看了半天,看来对js的理解还是不够透彻。

时间: 2024-12-15 12:42:39

一个有关原型的问题牵扯出的问题的相关文章

在51上写一个“OS”原型

自己在51单片机上实现任务调度器的记录过程,下面的文本内容,完整的图文文档传送到了文库.传送门 闲来无聊,便有了想写操作系统的念头.之前也用过ucso.rtt.raw-os,虽然没怎么深入应用,但对操作系统也有些认识.好奇心的驱使,终于在国庆这段时间里实现了这个“OS”.于是,便有了本文,用来记录自己实现一个OS的过程.当然,这个OS,可不像上面说的几个rtos那样,这个OS只是实现了任务调度功能,还不能算真正意义的OS,甚至编码上看起来很丑陋.由于51单片机相对简单,尽管资源上比较有限,但还是

做一个具有图片读入,写出,灰度化,黑白化的有图形界面的小软件

我们这一次的树莓基础的作业是做一个做一个具有图片读入,写出,灰度化,黑白化的小软件,我采用的是java,因为java有大量性能非常好的接口可用,譬如在图片这块,ImageIO,BufferedImage都是非常好用的,而我这一次作业也是使用这两个包. 首先我们要解决的是界面,界面可以直接用JFrame来打, 非常简单,我的界面有一个菜单栏和一个图片显示区,菜单栏有三个选项:文件,转换,保存,文件菜单有一个子菜单:打开文件,转换菜单有两个子菜单:变成灰度和变成黑白,保存菜单有三个子菜单:jpg,

61. 从1到n,共有n个数字,每个数字只出现一次。从中随机拿走一个数字x,请给出最快的方法,找到这个数字。如果随机拿走k(k>=2)个数字呢?[find k missing numbers from 1 to n]

[本文链接] http://www.cnblogs.com/hellogiser/p/find-k-missing-numbers-from-1-to-n.html  [题目] 从1到n,共有n个数字(无序排列),每个数字只出现一次.现在随机拿走一个数字x,请给出最快的方法,找到这个数字.要求时间复杂度为O(n),空间复杂度为O(1).如果随机拿走k(k>=2)个数字呢? [分析] 题目给出的条件很强,数字是从1~n的数字,限制了数字的范围:每个数字只出现一次,限制了数字出现的次数:随即拿走了一

[算法学习]给定一个整型数组,找出两个整数为指定整数的和(3)

问题描述: 设计一个类,包含如下两个成员函数: Save(int input) 插入一个整数到一个整数集合里. Test(int target) 检查是否存在两个数和为输入值.如果存在着两个数,则返回true,否则返回false 允许整数集合中存在相同值的元素 分析: 与[算法学习]给定一个整型数组,找出两个整数为指定整数的和(2)不同,这里需要算出的是存不存在这两个数,可以在上一篇的基础上修改一下数据结构,HashMap其中key是数值,value是数值个数,然后需要作两步判断,map中存在数

输入一个int型数据,计算出它在内存中存储时含1的个数

/******************************************************** 输入一个int型数据,计算出它在内存中存储时含1的个数 比如: 输入:5 输出:2 ********************************************************/ #include<iostream> int CountOne(int num) { int count = 0; while(num){ count++; num = num&am

编写一个程序,指定一个文件夹,能自动计算出其总容量

package wenjianyuliu;//编写一个程序,指定一个文件夹,能自动计算出其总容量import java.io.File;import java.util.ArrayList; public class Size {   static long size=0; private static ArrayList<String> filelist=new ArrayList<String>(); public static void main(String[] args)

【leetcode-03】给定一个字符串,请你找出其中不含有重复字符的最长子串的长度

开个新坑,leetcode上面做题目.下面是题目描述: <!-- 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出

遇到的一个JS原型的问题,还没得到解决

今天写代码的时候出现了一些问题.首先我的html文件是这样的 <div id = "tag_add" onclick="addUser()"></div> 恩恩,很清楚,调用了addUser()方法 var addUser = function () { var i=0; document.onkeydown = function(e){ var ev = document.all ? window.event : e; if(ev.keyC

2.3为方便旅客,某航空公司拟开发一个机票预定系统。 写出问题定义并分析系统的可行性。

为方便旅客,某航空公司拟开发一个机票预定系统.旅行社把预定机票的旅客信息(姓名.性别.工作单位.身份证号码.旅行时间.旅行目的地等)输入进 入该系统,系统为旅客安排航班,印出取票通知和账单,旅客在飞机起飞的前一天凭取票通知和账单交款取票,系统校对无误即印出机票给旅客. 写出问题定义并分析系统的可行性. 1>     目标:在一个月内建立一个高效率,无差错的航空公司机票预定系统 2>     存在的主要问题:人工不易管理,手续繁琐 3>     建立新系统 ①  经济可行性