js原型
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原型的更多相关文章
- JS原型链
JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...
- 深入分析JS原型链以及为什么不能在原型链上使用对象
在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...
- 【09-23】js原型继承学习笔记
js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...
- js原型链与继承(初体验)
js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...
- JS 原型链图形详解
JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...
- js原型解析
我们都知道javascript因为具有了继承以及变量等等一系列的特性之后才被人们认为具有一门编程语言的资格,在后续的不断发展中,js在原生的基础上扩展了基于jquery等等的库,甚至衍生了像node. ...
- 深入理解JS原型链与继承
我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...
- 学习zepto.js(原型方法)
学习zepto.js(原型方法)[1] 转载 新的一周,新的开始,今天来学习一下zepto里边的原型方法,就是通过$.进行调用的方法,也是可以通过$.fn进行扩展的方法: $.camelCase(): ...
- js原型链部分详细使用说明案例
1. 'index.html'文件 ```html <!DOCTYPE html> <html lang="en"> <head> <me ...
随机推荐
- 图的存储,搜索,遍历,广度优先算法和深度优先算法,最小生成树-Java实现
1)用邻接矩阵方式进行图的存储.如果一个图有n个节点,则可以用n*n的二维数组来存储图中的各个节点关系. 对上面图中各个节点分别编号,ABCDEF分别设置为012345.那么AB AC AD 关系可以 ...
- 55. Set Matrix Zeroes
Set Matrix Zeroes (Link: https://oj.leetcode.com/problems/set-matrix-zeroes/) Given a m x n matrix, ...
- oracle 常见恢复
author by :shawnloong 环境:windows 2008 r2 sp1 db:oracle 11g r2 做之前记得做个完整备份 ONFIGURE RETENTION POLICY ...
- FW: Chef集中管理工具实践之 (1) 环境部署
本文转载:http://heylinux.com/archives/2208.html Chef集中管理工具实践之 (1) 环境部署 目录结构Chef集中管理工具实践之 (0) 什么是ChefChef ...
- ORACLE-SELECT学习
(一)select格式:SELECT [ ALL | DISTINCT ] <字段表达式1[,<字段表达式2[,…] FROM <表名1>,<表名2>[,…] [W ...
- c/c++ 对象内存布局
一.对象内存查看工具 VS 编译器 CL 的一个编译选项可以查看 C++ 类的内存布局,非常有用.使用如下,从开始程序菜单找到 Visual Stdio 2012. 选择 VS 的命令行工具,按如下格 ...
- jsp配置项目时出错Deployment failure on Tomcat 6.x. Could not copy all resources to
转自:http://www.2cto.com/kf/201201/116853.html 今天在网上部署项目的时候出现在了问题 tomcat一直部署不上 网上查了一下 原因记下来供大家查看 Deplo ...
- Spring day04笔记(SVN讲解和回顾昨天知识)
spring day03回顾 事务管理 基于xml配置 1.配置事务管理器 jdbc:DataSourceTransactionManager hibernate:HibernateTransacti ...
- redis集群出现JedisNoReachableClusterNodeException异常(No reachable node in cluster)
上午午好好的,突然抛了如下异常: Exception in thread "main" redis.clients.jedis.exceptions.JedisNoReachabl ...
- COM符合名字对象建议使用的分隔符