JavaScript对象的隐藏链接详解

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

本文转载自"狂龙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 exist
Object.prototype.age = 56; // Every object is linked to Object.prototype by default
person.age; // 56

2. 函数:所有函数都是对象 ,其原型为Function.prototype。需要注意的是:不要混淆函数prototype属性和其原型。每个函数都有prototype属性,每个对象(函数也是对象)都有原型。
function foo(){
    console.log('foo');
}
foo.__proto__ == Function.prototype; //True

var bar = function(){
    console.log('bar');
}
bar.__proto__ == Function.prototype; //True

var 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 function
cat.__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

主要参考文献


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值