1、js基本类型和对象类型
js的简单类型包括数字(其中NaN为数字类型)、字符串(类似'A'为字符,js没字符类型)、布尔值、null值和undefined值。其他所有的值都是对象。数字、字符串和布尔值“貌似”是对象,因为它们拥有方法,但它们是不可变的,所以不是对象。js的对象时可变的键控集合(keyed collections)。在js中,数组、函数、正则表达式是对象。

2、js原型的重要知识点
首先要知道一个很重要的知识点,一句话:所有对象都有原型对象。


3、对比其他语言的理解
原型对象,就是其它语言中的类中的静态属性和静态方法,总之是静态-static就对了.原理是: 内存中只有一份。


4、原型链
每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。
按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是火狐和谷歌(ie除外)的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。因为ie不存在__proto__属性,所以在ie中,当对象创建后,对象的原型链就已经确定,无法更改。
由于原型对象本身也是对象,根据上边的定义,它也有自己的原型,而它自己的原型对象又可以有自己的原型,这样就组成了一条链,这个就是原型链,JavaScritp引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined.原型链一般实现为一个链表,这样就可以按照一定的顺序来查找。
prototype是构造器原型,其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__。实例如下:

 var base = {
name : "base",
getInfo : function(){
return this.name;
}
} var ext1 = {
id : 0,
__proto__ : base
} var ext2 = {
id : 9,
__proto__ : base
} document.write(ext1.id);
document.write(ext1.getInfo());
document.write(ext2.id);
document.write(ext2.getInfo());

结果:
0
base
9
base
图1

其中proto__属性在ie中无法看到,在谷歌、火狐浏览器的debug下能看到这个属性。上面实例在ie中,ext1.name为undefined。ie中,ext1的对象在debug中内部结构如下:

在谷歌浏览器debug中内部结构如下:


5、分析一(对象字面量)
示例代码如下:

 var base = {
name : "base",
getInfo : function(){
return this.name;
}
}

谷歌浏览器debug模式下base对象的内部结构如下:


6、分析二(普通函数)
示例代码如下:

 function test(){
document.write("hello world");
}

谷歌浏览器debug模式下base对象的内部结构如下:


7、分析三(构造函数)
示例代码如下:

 function createObj(name){
this.name = name;
}

var o3 = new createObj("yql");
谷歌浏览器debug模式下base对象的内部结构如下:


8、使用某对象作为原型的方法
当你创建一个新对象时,你可以选择某个对象作为它的原型。js提供的实现机制杂乱而复杂,但其实它可以被明显的简化。我们将给Object增加一个beget方法,这个方法创建一个使用原对象作为其原型的新对象。示例代码如下:

 if(typeof Object.beget !== 'function'){
Object.beget = function(obj){
var F = function(){};
F.prototype = obj;//__proto__属性在ie中不存在,只能通过构造函数的prototype来设置原型
return new F();
};
}
var obj = {
msg:"hello world"
};
var newObj = Object.beget(obj);
document.write(newObj.msg);//hello world

谷歌浏览器debug模式下base对象的内部结构如下:

ie浏览器debug模式下base对象的内部结构如下:


9、我的理解
示例一:

 var obj = {
name : "zhangsan"
};
document.write(obj.name)//zhangsan
document.write(obj.age)//undefiend
Object.prototype.age = 28;
document.write(obj.age);//

示例二:

function ObjConstructor(name){
this.name = name;
}
var obj = new ObjConstructor("zhangsan");
document.write(obj.name+"<br />");//zhangsan
document.write(obj.age+"<br />");//undefiend
ObjConstructor.prototype.age = 28;
Function.prototype.sex = "M";
Object.prototype.home = "hb";
document.write(obj.age+"<br />");//28,obj.__proto__===ObjConstructor.prototype,即obj的原型为ObjConstructor.prototype对象
document.write(obj.sex+"<br />");//undefined,说明对象obj不能访问到Function.prototype
document.write(obj.home+"<br />");//hb,obj的原型的原型为Obj.prototype对象

示例三:

 var str = new String();
document.write(str.name);//undefined
String.prototype.name="zhangsan";
Object.prototype.age = 28;
Function.prototype.sex = "M";
document.write(str.name);//zhangsan,str的原型指向String.prototype对象
document.write(str.age);//28,str的原型的原型指向Object.prototype对象
document.write(str.sex);//undefined,str的原型链中没有指向Function.prototype对象

根据上面3个示例,可以得出以下几点内容:
1、对象在构造时,js引擎会设定该对象的原型(虽然谷歌、火狐的浏览器下可以修改对象原型的指向,但是ie中无法修改,而且按照标准,原型为隐藏的,不推荐可以修改)。对象构造完成后,对象的原型指向
的对象无法更改。如示例一中obj的原型指向Object.prototype对象,示例二中obj的原型指向ObjConstructor.prototype对象,示例三中str的原型指向String.prototype对象,这3个对象的原型指向的对象不能修改为
其他对象,只能是对应构造函数的prototype指向的对象。
2、只有函数有prototype属性,普通对象没有prototype属性。对象构造后,对象的原型指向其构造函数的prototype属性的对象。如示例一中obj的构造函数为function Object(){...},示例二中obj的构造函数为
function ObjConstructor(name){...},示例三中str的构造函数为function String(){...},所以他们的原型指向分别为Object.prototype对象、ObjConstructor.prototype对象和String.prototype对象。
3、自定义的函数的构造函数为function Function(){...},所以自定义的函数的原型为Function.prototype对象。如示例二中ObjConstructor的原型指向Function.prototype对象。
4、构造函数的prototype属性指向普通对象(不是函数),所以构造函数.prototype对象的原型为Object.prototype(不包括多层构造的情况)。如示例二中ObjConstructor.prototype的原型为Object.prototype
5、__proto__属性为对象(包括函数)的原型属性(ie中该属性为隐藏,按标准,该属性应该为隐藏的,但是可以用该属性来理解原型),prototype为函数的属性。当使用构造函数构造对象后,对象的原型
(即对象.__proto__)为构造函数的prototype(构造函数.prototype)所指向的对象。 容易理解错误的是,虽然对象的原型与prototype有紧密的联系,但是对象的原型不是对象的prototype属性。
6、按照java语言,可以这样理解:构造函数为类,所以推荐构造函数名称首字母大写。对象的原型的属性或方法可以理解为类的属性或方法(即java类中用static修饰的属性或方法)。

js原型的更多相关文章

  1. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  2. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  3. 【09-23】js原型继承学习笔记

    js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...

  4. js原型链与继承(初体验)

    js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...

  5. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  6. js原型解析

    我们都知道javascript因为具有了继承以及变量等等一系列的特性之后才被人们认为具有一门编程语言的资格,在后续的不断发展中,js在原生的基础上扩展了基于jquery等等的库,甚至衍生了像node. ...

  7. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  8. 学习zepto.js(原型方法)

    学习zepto.js(原型方法)[1] 转载 新的一周,新的开始,今天来学习一下zepto里边的原型方法,就是通过$.进行调用的方法,也是可以通过$.fn进行扩展的方法: $.camelCase(): ...

  9. js原型链部分详细使用说明案例

    1. 'index.html'文件 ```html <!DOCTYPE html> <html lang="en"> <head> <me ...

随机推荐

  1. OAF_文件系列2_实现OAF导出CSV格式文件ExportButton(案例)

    20150727 Created By BaoXinjian

  2. ADF_Starting系列8_使用EJB/JPA/JSF通过ADF构建Web应用程序之扩展UI Method

    2013-05-01 Created By BaoXinjian

  3. oracle判断某个字符在字段里出现过几次

    SELECT LENGTH(字段名)-LENGTH(REPLACE(字段名,'字符','')) FROM 表名;

  4. java maven诡异的错误no class found

    从服务器下载一个java web项目,启动老提示no class found,查看maven依赖库,相关的jar包都已经引入.同样一个项目,在别的机器都可以运行,唯独在我本机运行出错. 为了排错,将其 ...

  5. 24. Longest Consecutive Sequence

    Longest Consecutive Sequence Given an unsorted array of integers, find the length of the longest con ...

  6. 剑指Offer:面试题27——二叉搜索树与双向链表(java实现)

    问题描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路: 将树分为三部分:左子树,根结点,右子树. 1.我们要把根结点与左 ...

  7. Linux学习笔记——切换并取代用户身份命令——su

        再次从头好好的学习Linux,本着以免轻易忘记,以备后用的原则,将我觉得常用或者好玩的linux命令记录在这,注意:我的实验环境是 Ubuntu 14.04.1 su 这个命令我经常使用,因为 ...

  8. 解决EditorLineEnds.ttr被锁定导致Delphi2006-2010无法启动的问题

    在批处理最后增加了启动Delphi的命令.将批处理和Delphi放在同一目录即可. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  9. 第五百八十二天 how can I 坚持

    好吧,是我错了,昨天,做好自己就行了,别人怎么样是别人的事,永远保持一颗单纯向上的心. 时间过得真快,明天又周六了.. 睡觉.

  10. Python 前端之JS

    JavaScript由浏览器编译运行 JS的导入方式有两种,一种直接定义,第二种通过src引入:可以存放在<head>头部,但是强烈建议放在<body>的最下面,因为如果你引入 ...