JavaScript 的 Prototype 原型链详解(转)
来源:互联网 发布:淘宝保险平台 编辑:程序博客网 时间:2024/06/08 19:36
JS 是基于原型的语言,但是如果问及 JS 原生对象(Object,Function,Array,Date 等)的这 个原型链长什么样子?估计能回答出来的人就少了,我开始也非常糊涂,后来决心一定要好 好搞一下,花了 2 天功夫基本算是明白了,分享如下:
测试环境:Firefox、Firebug;
为做好铺垫,按顺序解释如下概念:
1)类型、原生类型、对象类型(types、primitive types、
object types)
不像我们在学习 JAVA 时,被告知 JAVA 是完全 OOP 的语言:class 是一类具有共同特 点的物体的抽象,object 是某个 class 下具体的一个 实现,Object 类是所有类的顶层父类, 对 Java 的认知是从类与对象开始的;Javascript 则不然,它是从类型(type)开始,在各类 语言中 遇到的 number,string, boolean, object, function,array 等都属于类型。
这些类型在 JS 中分为两大类:原生类型与对象类型,原生类型包括:number,string, bool, null, undefined;剩下的非原生类型对象都属于对象类型,包括:object, array, function 等, 那这里的 object 专指具有属性(attribute)的对象,在 Firebug 中的代码示例如下:
// 1) primitive types
1
log(typeof 1);
// number
2
log(typeof "");
// string
3
log(typeof false);
// boolean
4
log(typeof undefined);
// undefined
5
log(typeof null);
// object
null 是个特列,属于原生类型;
6
log(null instanceof Object);
// false
7
// 2) object types.
8
log(typeof new Object);
// object
9
log(typeof new Function);
// function
10
log(typeof new Array);
// object
11
12
13
14
log(opts.call(new Object));
// [object Object]
15
log(opts.call(new Function));
// [object Function]
log(opts.call(new Array));
// [object Array]
判断某个值是什么大的类型没有意义,往往需要判断它是什么原生类型或者对象类型: 判断原生类型,可以使用 typeof 关键字;判断对象类型,可以使用 toString()方法;
2)prototype 与__proto__的区别
两者都是对象类型的属性,并非所有的对象类型都有 prototype 属性,一般只有 function 对象才有 prototype 属性(除非主动赋值), 它指向的是一个对象,将来会被多个该 function 的实例所继承(或者说该对象处于多个实例的原型链上);__proto__才是真正的原型链的实 际指 针,然而许多浏览器并不对外公开这个属性,Firefox 暴露出这一属性,仅供开发人员 理解,但不推荐开发中使用。下面我们用一段代码来做验证:
1
// 1) prototype 属性:一般只有 function 对象拥有
2
log((new Object).prototype);
// undefined
3
log([].prototype);
// undefined
4
log((new Function).prototype);
// anonymous {}
5
// Function, Object, Array 是 function 对象
6
log(Function.prototype);
// function()
7
log(Object.prototype);
// Object {}
8
log(Array.prototype);
// []
9 // 2) __proto__属性:指向该对象原型链的上一端
10log((Object.prototype).__proto__);
// null
11 log((Function.prototype).__proto__);
// Object {}
12log(Object.__proto__);
// function()
13log(Function.__proto__);
// function()
14// function 对象 Company 的 prototype 属性所指的对象处于实例对象的原型链上 15var Company = function(name){
16 this.name = name; 17};
18var c1 = new Company("IBM"); 19var c2 = new Company("Alibaba");
20console.log(c1.__proto__ == Company.prototype); // true 21console.log(c2.__proto__ == Company.prototype); // true
上面的示例我们确认了__proto__才是原型链中对象之间从下到上的联系的桥梁,那么 既然是链总该有个头吧?要是一直找不到头,就成死链了,在 JAVA 里所有对象都会继承来 自最顶层父类 Object 的方法一样,如:toString 方法,JS 中会继承哪些方法呢?
3)原型链的最顶端
既然__proto__是链的索引,那么我们是否可以辛苦测试一下常用的对象呢?
1
// 原型链的顶端
2
log((Object.prototype).__proto__);
// null
3
log(Function.prototype.__proto__ == Object.prototype);
// true
4
log(Object.__proto__
== Function.prototype);
// true
5
log(Function.__proto__
== Function.prototype);
// true
6
log(Array.__proto__
== Function.prototype);
// true
7
log(Company.__proto__
== Function.prototype);
// true
8
log(Object.__proto__
== Function.prototype);
// true
9 log(Company.prototype.__proto__ == Object.prototype);
// true
10log(c1.__proto__
== Company.prototype);
// true
经过上面的比较后,我们基本就可以画出这个原型链顶端的样子了, 如下图:
4)了解原型链最顶端的意义
意义似乎应该放在前面讲更突出重要性,就当不求甚解吧,个人理解有如下意义:
A) 清楚对象的继承结构,知道它有哪些父类(父类:指的是该对象原型链向上方向的对
象);
B) 了解并调用父类的方法,不会混淆功能;
C) 多个对象共享原型链的某一段时,方便调试;
针对 A 好处,我们可以更好的理解 instanceof 关键字的作用;
针对 B 好处,我们可以调用不同父类的方法完全不同的判断需求,比如:
Function.prototype.toString.call(obj) 方法 用于输出 function 对象的定义代码 , Object.prototype.toString.call(obj)方法用于输出该对象所属的 object 类型;
针对 C 好处,这个便于理解复杂 JS 框架中对象的内存管理模型,比如:DOJO 框架。
- JavaScript 的 Prototype 原型链详解(转)
- JavaScript的Prototype原型链详解
- JavaScript prototype原型和原型链详解
- JavaScript-- prototype原型和原型链详解
- JavaScript 原型链、prototype、__proto__详解
- javascript 原型链详解 prototype和__proto__
- JavaScript的prototype(原型)
- JavaScript学习--Item15 prototype原型和原型链详解
- Javascript 原型、原型链、prototype以及__proto__详解
- javascript prototype 原型链
- Javascript prototype 原型链
- 你不知道的JavaScript--Item15 prototype原型和原型链详解
- javascript中的原型(prototype)及原型链的继承方式
- javascript中的原型(prototype)及原型链的继承方式
- JavaScript 的原型对象 Prototype
- javascript原型prototype的由来
- javaScript prototype原型的理解
- Javascript讲解系列之一 Prototype原型链详解
- MySQL explain执行计划解读
- Intellij IDEA 下载 激活(15.02)
- php session 入库
- 动态加载JavaScript
- poj 1182 食物链(并查集)
- JavaScript 的 Prototype 原型链详解(转)
- Android26_Bitmap二次采样
- 2015年,从毕业到工作的几点感悟(Android开发新人)
- 在Xcode7.x中安装Alcatraz
- cocos2d-x-2.2.3和vs2012环境配置
- jquery.timers使用说明
- 获取自定义实体类注解工具类FieldHelper
- 用eclipse向tomcat部署中tomcat设置(备忘)
- cvSplit(),cv图像颜色通道分割和融合