轻松搞定javascript原型链 _proto_

//如有错误或不同观点,欢迎批评与讨论!

首先,prototype出现的目的,是为了解决 代码重用
的问题 , prototype 相当于是在内存上划分出一个公共的区域, 专用于存放 实例化对象 的相同方法或属性,
一份代码,人人可用;

为方便理解,我们可以先把prototype 当作是CSS中的
class,在prototype上加方法和属性,那么其它对象就会拥有这些方法和属性,
但这些代码紧有一份!

<script>
function Person()
{
this.name = ‘张三‘; 
this.id = function (){ alert(‘身份证‘) };
}
Person.prototype.say = function (){ alert(‘说话‘); }

var P1 = new Person();
var P2 = new Person();

console.log(P1);
console.log(P2);
console.log(P1.name === P2.name);    //true
console.log(P1.id === P2.id);    //false
console.log(P1.say === P2.say);    //true
</script>

/---------------------------------------------------------------/

运行上面代码,从控制台中可以看出:

1.name,
id 都是直接放在 new出来的对象上的, 他们的name的比较是相等的(因为字符串是基本类型,所以为true),而id比较 是false,这是因为
function 是复合数据类型,比较的是引用值,这两个 id 分别属于两个不同的对象,
引用不一样,所以为false;

2.我们直接 P1.say()
是可以运行的,但是从控制台可看出,P1和P2并没有say这个方法,这个方法其实是属于 Person.prototype
这个对象的,那为什么P1,P2可以使用这个方法呢?请看下图

3.从控制台中我们还可以看到这样的个东东:_proto_ ; 它就是JS的 原型链 ,我们是访问不了它的, 但是可以在控制台中看到它,
其实 _proto_ 就是将 实例对象 P1、P2 和 类(构造函数)建立起一个联系,通过这个 原型链
可以找到Person.prototype这个内存公共空间里的 所有公共方法和属性; 从上图可以看出, say这个方法正是在里面,
而这个constructor是哪里来的呢? 这个是当我们定义Person函数的时候, 浏览器自动给我们添加的, 并且指向 Person它自己:
Person.prototype.constructor = Person; 这个属性很容易在不经意间被我们修改, 出现这种情况时我们需要手动修正一下,
JQ也是这样处理的, 详情请看最后面的补充, 现在继续上面的讨论;

4.从上图中我们还可以看到 _proto_ :Object, 原型链 又将P1, P2 和 Object类联系了起来,
这个,P1,P2 就可以使用 Object.prototype 这个内存公共空间里的
所有公共方法和属性,虽然Person.prototype上没有这些方法和属性, 我们 alert( P1.hasOwnProperty(‘id‘) )
是可以得到true的,因为 它们在同一条原型链上。

从上图还可以看出, 浏览器也给Objcet加了这样的个属性:
Object.prototype.constructor = Object; 那为什么 P1.constructor 会是Person, 而不是Object呢,
因为原型链是 这样的 P1 _proto _ Person _proto _ Object ,
P1在Person.prototype处找到了constructor这个属性,就不会继续往下找,只有找不到的时候才往下找。

5.原型链的尽头是Object,
从上头可以看出,没有 _proto_
再连接到别的地方了。

6.所以,只要是在同一原型链上,实例化对象就可以使用这些方法和属性,如果有重复的方法或属性,
距离近的会覆盖距离远的。

下面我做了个小图给大家参考参考 :

-如果图片看不清,请单击鼠标右键,复制图片地址,粘贴在浏览器地址栏上打开------------------------------------------------------------------------------------------------------------------------------------------------------

a.上面可看出,
房子嘛, 不是说你一出生就有的, 自己 没有可以先住老爸的, 如果老爸没有嘛, 老爸他哥有, 你出门在外, 也可以先去住着先的, 再没有嘛再去别的亲戚家住下先,
最远的尽头是 Object,

b.如果你老爸买房子了, 那你就别去你大伯家住啦,
你就去你老爸那住,

c.如果你有能力啦,买房子啦, 就自己搬出来住啦!(相当于加 this.sleep ,优先级高于
prototype上的sleep,和css中的
id相似)

补充:

上面说到的我们会在不经意间会修改,Person.prototype.constructor这个属性,是哪种情况呢?

<script>
function Person()
{
this.name = ‘张三‘; 
this.id = function (){ alert(‘身份证‘) };
}
//Person.prototype.say = function (){ alert(‘说话‘); }
Person.prototype = { say: function (){ alert(‘说话‘) }}

var P1 = new Person();
console.log(P1.constructor)
</script>


Person.prototype也是对象,所以可以改成下面的写法,但是改成这样的写法后,我们会看到,P1.constructor
竟然变成了 function Object() { [native code] }, 怎么会变成 Object
呢?

是这样的,第一种写法, 是给 Person.prototype 对像添加属性; 而第二种写法, 是直接把一个对象{
}覆盖了 Person.prototype 这个对像, 这种写法的{ }对象是 Object 实例出来的, 所以嘛, 这个
P1.constructor当然就是Object啦;

像上面的,你老爸把房产证卖给都给Objcet了,虽然你还住着(别人还没赶你走~~),
你说这个房子的主人是谁?

所以我们需要手动修正一下,Person.prototype.constructor =
Person;

下图可以看到,JQ也是这样处理的:

转载至,http://www.websha.cn

轻松搞定javascript原型链 _proto_,码迷,mamicode.com

时间: 2024-10-27 09:35:10

轻松搞定javascript原型链 _proto_的相关文章

轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)

hey,guys!我们一起总结一下JS预解析吧! 首先,我们得搞清楚JS预解析和JS逐行执行的关系.其实它们两并不冲突,一个例子轻松理解它们的关系: 你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解析),但吃的时候还是一口一口的吃(JS逐行执行)! OK,解决下面五个问题,JS预解析就算过了~~(前提:对JS变量作用域有清晰理解) 一.JS预解析是什么? 其实就是对程序要用到的材料(变量,函数)给一个初始值,并存到一个表中(我自己虚构的),当程序运行到那一行时,就来这个表看有没有初始值,没有就

教你轻松搞定javascript中的正则

1 正则表达式概述 1.1 什么是正则表达式 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式.在Javascript中,正则表达式也是对象.正则表通常被用来检索,替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母.数字或者下划线,昵称输入中文(匹配).此外,正则表达式还常用于过滤掉页面内容中的一些敏感词,或从字符串从获取我们需要的特定部分(提取)等. 1.2 正则表达式特点 灵活性.逻辑性和功能性非常强 可以迅速地用极其简单的方式达到

轻松搞定javascript日期格式化问题

1 Date.prototype.format = function(f){ 2 var d = this 3 f = f || "yyyy-MM-dd hh:mm:ss" 4 return f.replace(/[yMdhms]+/g, function(item){ 5 switch (item) { 6 case "yyyy": 7 return d.getFullYear() 8 break 9 case "MM": 10 return

韩顺平_轻松搞定网页设计(html+css+javascript)_第34讲_js超级玛丽小游戏

韩顺平_轻松搞定网页设计(html+css+javascript)_第34讲_js超级玛丽小游戏_学习笔记_源代码图解_PPT文档整理 分类: PHP 2012-12-12 15:01 4256人阅读 评论(0) 收藏 举报 文西马龙:http://blog.csdn.net/wenximalong/ 采用面向对象思想设计超级马里奥游戏人物(示意图) 怎么用通过按键,来控制图片的位置 这个小游戏,用面向对象会很方便,不用面向对象会很麻烦很麻烦,比如以后要讲解的坦克大战的游戏,要是用纯的面向过程或

一行代码轻松搞定各种IE兼容问题,IE6,IE7,IE8,IE9,IE10

在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题? 百度源代码如下: 1 <!Doctype html> 2 <html xmlns=http://www.w3.org/1999/xhtml xmlns:bd=http://www.baidu.com/2010/xbdml> 3 <head> 4 <meta http-equiv=Content-Type content=

轻松搞定Ajax(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)

hey,guys!今天我们一起讨论下ajax吧!此文只适合有一定ajax基础,但还是模糊状态的同志,当然高手也可以略过~~~ 一.概念 Ajax(Asynchronous Javascript + XML(异步JavaScript和XML )) 二.效果 实现无刷新效果,向后台异步的取数据(不是只有AJAX才能实现这样的效果的哦,如img , script标签中的src属性也可以实现一样的效果,可以自己尝试一下哦) 三.本质 可能我们在学习过程中会觉得ajax好难,我也是这样过来的,我觉得是我们

深入理解JavaScript原型链

前言 最近碰到一个题,大家可以试下. Object.prototype.a = function() { console.log("aaa "+this.name); }; Function.prototype.b = function() { console.log("bbb "+this.name); }; function Person(name) { this.name = name; } var person = new Person("Chin

六步轻松搞定,自建APP不求人

随着互联网浪潮的席卷,越来越多的传统企业开始涉足互联网领域.无论是出于企业转型升级考虑,还是受市场整体环境的驱动,很多企业凭借某一领域的绝对优势,浩浩荡荡进军移动互联网领域,通过自建APP的方式,推出属于自己的移动端应用产品. 不少企业在探寻如何自建APP的过程中,遇到的第一个决策性难题就是:自建APP开发团队还是外包APP建设?其实对于大多数企业而言,由于企业内部组织架构设置问题,尚没有配备完善的自建APP开发团队,同时财政预算有限,难以承担整体自建APP工作.对于这类中小型企业而言,如何能够

centos下yum安装lamp和lnmp轻松搞定

centos下yum安装lamp和lnmp轻松搞定,到底多轻松你看就知道了,妈妈再也不担心不会装lamp了. 很辛苦整理的安装方法,会持续更新下去.凡无法安装的在评论里贴出问题来,会尽快解决.共同维护一个可用yum可用更新. 软件列表:php5.4 apache2.2 mysql5.5 nginx1.8 centos6.x rpm -Uvh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ng