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. MapReduce格式与类型

    MapReduce Types MapReduce是一个简单的数据处理模型,map与reduce的输入和输出类型都为key-value形式的键值对. map: (K1, V1) → list(K2, ...

  2. CSS布局概述

    1.HTML5文档类型 由于Bootstrap使用了HTML5特定的HTML元素和CSS属性,所以使用Bootstrap的时候,所有的HTML文件都需要在其顶部引用HTML5的DOCTYPE属性,如下 ...

  3. JAVA为什么要配置环境变量,怎样配置

    自己总结些再加抄点:安装JDK后要配置环境变量,主要有三个:1 JAVA_HOME ->为JDK的安装目录,如:F:\JAVA\jdk1.6.0_042 CLASSPATH ->到哪里找需 ...

  4. Python基础篇【第1篇】: Python基础

    Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  5. ubuntu NTP server 搭建

    ubuntu server ntp时间同步服务器安装及使用一.服务端1 apt-get install ntp 2 安装后默认启动服务,如果没有启动,启动之. /etc/init.d/ntp star ...

  6. ORCLE数据库导出导入

    从一个用户导出用户所有结构数据 再导入另一个用户里面 ORACLE导出用户下的数据库  exp 命令 用户名/密码服务名 文件地址  owner=(用户名)exp COM_HIOSC_OLD/COM_ ...

  7. MXS 编辑器外观

    Tool > Open User Options File # Give symbolic names to the set of colours used in the standard st ...

  8. hive中order by,sort by, distribute by, cluster by作用以及用法

    1. order by     Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排序,所以说,只有hive的sql中制定了order by所有的 ...

  9. NAT协议

    NAT服务器的设定   NAT的全名:Network Address Translation;即网络地址的转换: iptables指令就能够修改IP封包的表头数据,IP的目标地址,源地址都可以修改. ...

  10. 64 位 Ubuntu 下 android adb 不可用解决方法

    解决方案: 安装ia32-libs 在终端执行 sudo apt-get install ia32-libs 其间会提示所依赖的某些包不存在,直接 sudo apt-get 安装即可.