JavaScript对象的隐藏链接详解

来源:互联网 发布:fpga串口多个数据 编辑:程序博客网 时间:2024/06/05 05:47

原创声明:本文除了标明引用的内容外,都为本人原创,请尊重本人的知识产权,不能用于商业用途。欢迎转载,转载请在文章开头处插入以下内容:

本文转载自"狂龙ing”的Blog,地址为“http://blog.csdn.net/kuanglong2016/article/details/17549055"

背景知识

        ECMAScript中有5种基本数据类型:Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object(对象),ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述6种数据类型之一(参见“JavaScript高级程序设计(第3版)”)。在ECMAScript中,函数也是对象
        ECMAScript是一种语言标准,JavaScript则是ECMAScript的一种实现,并提供了浏览器和网络相关的一些特性。下面统一使用JavaScript来描述。

概念和原理

        JavaScript是一种原型语言,所有的对象都有一个原型(Prototype Link或 Hidden Link),对象通过一个叫做[[Prototype]]的“指针”指向其原型。虽然在脚本中没有标准的方式访问[[Prototype]],但Firefox、Safari和Chrome在每个对象上都支持一个属性__proto__,作为[[Prototype]]的实现。所以在这些浏览器中,对象可以通过的__proto__来访问其原型。
        原型可以为对象提供额外的属性或方法,类似于Java或C++中的父类,但JavaScript中的原型是一种动态绑定,而且是”对象继承”不是“类继承”,原型对象所做的任何修改都能够立即从实例对象上反映出来。

原型详解

这里首先需要特别强调JavaScript的两个特点:
1. 所有对象都有原型对象,包括字面量对象、函数以及构造函数生成的对象;
2. 对象的原型也是对象,所以也有其自己的原型对象,根据原型链一直延伸,最后都指向Object.prototype,而Object.prototype的原型为Null。

1. 字面量对象:原型为Object.prototype
var person = {      "First_Name": "Barry",      "Last_Name": "Steyn",    "do_Something": function() { alert('something'); }}
修改原型Object.prototype可以增强字面量对象
person.age; // undefined - property age does not existObject.prototype.age = 56; // Every object is linked to Object.prototype by defaultperson.age; // 56

2. 函数:所有函数都是对象 ,其原型为Function.prototype。需要注意的是:不要混淆函数prototype属性和其原型。每个函数都有prototype属性,每个对象(函数也是对象)都有原型。
function foo(){    console.log('foo');}foo.__proto__ == Function.prototype; //Truevar bar = function(){    console.log('bar');}bar.__proto__ == Function.prototype; //Truevar person = {    name: "person name",    show: function(){        console.log(this.name);    }}person.show.__proto__ == Function.prototype; //True
可以通过修改原型Function.prototype来增强所有函数
Function.prototype.subtract= function(num1, num2){    return num1 - num2;};foo.subtract(20, 3); //17

3. 构造函数生成的对象,其原型为其构造函数的prototype
var Animal = function(name) {    this.name = name;}var cat = new Animal('fluffy'); //Using new to invoke the functioncat.__proto__ == Animal.prototype; //True
 a) Animal是一个对象(因为所有函数都是对象),其原型是Function.prototype
 b) Animal是函数,所以有一个prototype属性
 c) cat也是一个对象,由Animal函数构造出来,是对象就有原型,其原型与字面量对象不同,不是Object.prototype而是Animal.prototype

这里问一个问题:Animal.prototype的原型是什么? 当然就是Object.prototype

特别需要注意的有
Object.__proto__ == Function.__proto__ == Function.property, 因为Object和Function都是函数
Object函数构造的对象的原型是Object.prototype

功能作用

使用原型可以实现非常灵活的继承,比如Douglas Crockford提出的原型式继承
function object(o){    function F(){}    F.prototype = o;    return new F();}var pussy_cat = object(cat);pussy_cat.__proto__ == cat; //True

总结

字面量对象: 原型 == Object.prototype
函数: 原型 == Function.prototype
构造函数生成对象: 原型 == [Constructor].prototype

主要参考文献

1. JavaScript高级程序设计(第3版)
2. JavaScript: The Good Parts
3. Javascript: Object Prototypes

0 0
原创粉丝点击