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. 利用Manacher算法寻找字符串中的最长回文序列(palindrome)

    寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如aba,abba等)算是挺早以前提出的算法问题了,最近再刷Leetcode算法题的时候遇到了一个(题目),所以就顺便写下. 如果用正反 ...

  2. Crt单元

    一.调用单元例:uses crt; 二.清屏例:clrscr; 三.移动光标例:gotoxy(a,b);其中a表示列号,b表示行号 四.清行例:clreol;清除光标所在行光标上及以后的所有字符 五. ...

  3. Python偏函数

    偏函数 一个带n 个参数,curried 的函数固化第一个参数为固定参数,并返回另一个带n-1 个参数函数对象 >>> from functools import partial & ...

  4. dom4j生成xml

    package com.yunfengtech.solution.business; import java.io.FileOutputStream; import org.dom4j.Documen ...

  5. Codeforces724D [字符串][乱搞][贪心]

    /* 不要低头,不要放弃,不要气馁,不要慌张 题意:给你一个区间长度n和一个字符串,要求在字符串中选择一些symbol使得字符串的任意长度为n的子区间都存在至少一个symbol. 任意选取symbol ...

  6. Chap4: question: 19 - 28

    19. 二叉树的镜像(递归) 即:交换所有节点的左右子树.从下往上 或 从上往下 都可以. #include <iostream> #include <string> usin ...

  7. 11. Evaluate Reverse Polish Notation

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  8. FreeBSD 10 中文环境

    中文字体位置 FontPath        "/usr/local/lib/X11/fonts/misc/:unscaled" FontPath        "/us ...

  9. 使用JDBC处理Oracle大数据

    一.Oracle中大数据处理 在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了.因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种 ...

  10. MBW内存测试

    在测试前,理应了解本机所具备的特点,比如CPU频率.内存频率.内存大小,等等信息. 查看CPU用如下命令(多少个核,频率,特性等): cat /proc/cpuinfo 查看内存用如下命令:(只有当前 ...