手记

JavaScript原型继承的基本规则

基本规则

JavaScript是一门基于原型的面向对象语言,所有的JavaScript对象都是从某个对象上克隆而来的。以下为JavaScript原型继承的四个基本规则:

1、所有的数据都是对象。

在JavaScript中,不管是基本类型还是引用类型,除了undefined之外,一切都是对象。number、boolean、string这几种基本类型也可以通过“包装类”的方式变成对象来处理。这些对象追根溯源都来源于一个根对象,即Object.prototype对象。Object.prototype对象是一个空的对象。我们在JavaScript遇到的每个对象,实际上都是从Object.prototype对象克隆而来的,Object.prototype对象就是它们的原型。

2、要创建一个对象,就要找到一个对象作为原型并克隆它。

JavaScript的函数既可以作为普通函数被调用,也可以作为构造函数被调用。当使用new运算符来调用函数时,此时的函数就是一个构造函数。用new运算符来创建对象的过程,实际上也只是先克隆Object.prototype对象,再进行一些其他额外操作的过程。我们可以通过下面这段代码来理解new运算的过程:

function Obj(name, age) {
    this.name = name;
    this.age = age;
    if (typeof(this.getName) != "function") {
        Obj.prototype.getName = function() {
            return this.name;
        }
    }
}

function NewObj(Constructor, array) {
    //实例化构造函数 Object
    //实际上就是复制 Object.prototype对象上的所有方法创建新对象
    var obj = new Object();
    //初始化新对象的原型对象
    obj.__proto__ = Constructor.prototype;
    //初始化新对象的实例对象
    Constructor.apply(obj, array);
    //返回新对象
    return obj;
}

var a = NewObj(Obj, ["Tom", 20]);

3、 对象会记住它的原型。

如果发出的请求想在一个链条中依次往后传递,那么每个节点都必须知道它的下一个节点。同理,要完成JavaScript语言中的原型链查找机制,每个对象至少应该先记住它自己的原型。就JavaScript的真正实现来说,其实并不能说对象有原型,而只能说对象的构造函数有原型。JavaScript给对象提供了一个名为__proto__的隐藏属性,某个对象的__proto__属性默认会指向它的构造函数的原型对象,__proto__就是对象跟“对象构造函数的原型”联系起来的纽带。

4、如果对象无法响应某个请求,它会把这个请求委托给它的构造函数的原型。

这条规则是原型继承的精髓所在。从前面的学习中,我们已经了解到,当一个对象无法响应某个请求的时候,它会顺着原型链把请求传递下去,直到遇到一个可以处理该请求的对象为止。但是在JavaScript中,每个对象最初都是从Object.prototype对象克隆而来的,如果是这样的话,我们只能得到单一的继承关系,即每个对象都继承自Object.prototype对象,这样的对象系统显然是非常受限的。实际上,虽然JavaScript的对象最初都是由Object.prototype对象克隆而来的,但对象构造函数的原型并不仅限于Object.prototype上,而是可以动态指向其他对象。这样一来,当对象a需要借用对象b的能力时,可以有选择性地把对象a的构造函数的原型指向对象b,从而达到继承的效果。

例子:

var obj = { name: 'sven' };

var A = function(){};
A.prototype = obj;
var a = new A();
console.log( a.name );  
// 输出:sven

文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。

0人推荐
随时随地看视频
慕课网APP