去见对象爸爸

271 阅读2分钟

这是继上一篇《找对象》之后的系列文章,对象的爸爸。

追根溯源,如果我的男朋友H姓刘,那基本上他的爸爸一定也姓刘吧(排除特殊情况),他们都属于刘氏家族,身体里都留着刘氏的血,也都冠着‘刘’的姓,起码到H的爸爸这一代,还都是‘刘’姓,H的爸爸创造了H,所以H也是‘刘’姓,也就是说H由H的爸爸创造。

根据上一篇文章创建对象的方法第三种,构造函数创建,比如H的爸爸是一个构造函数,那么创建H的过程如下:

function HFather(){};
HFather.prototype.surname = '刘';
let H = new HFather();
H.surname

执行上面的代码得到'刘',为什么呢?H为什么会拥有属性surname呢?并且还可以得到surname的属性值呢?

在js的语言世界里,包含两个有意思的函数对象,一个是Object(),一个是Function();每个Object都默认包含一个__proto__,每个function都有prototype对象,而object的__proto__指向创建该对象的构造函数的prototype对象;

以上面的代码为例,H是由函数HFather创建的对象,H的__proto__指向HFather的prototype;

__proto__和prototype都叫原型,但两者是有区别的:

1.__proto__是对象的,prototype是函数的;

2.__proto__仅仅是解析出来的,是不能直接使用的,而prototype是可以直接使用的;

3.prototype也是一个对象,所以prototype也有__proto__;

在执行H.surname这句代码时,会先找H有没有surname这个属性,如果没有就向下找该对象的__proto__是否有surname属性,

如图,找到了,如果在第一层的__proto__没有找到,会继续向下寻找,直到Object,找不到将会报错。

仔细看上面的图,H对象的__proto__下方还有一个__proto__,这是因为第一个__proto__指向的是HFather的prototype,而prototype也是一个对象,Object是所有对象的根,在这个例子中,HFather的prototype的__proto__指向了Object,由__proto__串联起来,就构成了原型链。

如果H还有一个和蔼的爷爷,他们家从爷爷开始肤色都有些黑,如何表达呢?也许如下:

    function Family (){
        this.surname = '刘';
    };
    let HGrandpa = new Family();
    HGrandpa.color = '黑';
    function HGrandpaFun(){};
    HGrandpaFun.prototype = HGrandpa;
    
    let HFather = new HGrandpaFun();
    function HFatherFun (){};
    HFatherFun.prototype = HFather;
    
    let H = new HFatherFun();
    H.surname

以上代码并不规范,仅仅表达原型链的例子。

最后贴上一个网上找的原型链面试题,大家可以答一下哦~

function Animal() {
    this.name = 'Animal';
}

Animal.prototype.changeName = function (name) {
    this.name = name;
}

function Cat() {
    this.name = 'Cat';
}

var animal = new Animal();

Cat.prototype = animal;

var cat = new Cat();

animal.changeName('Tiger');

console.log(cat.name)

A. Animal

B. Cat

C. Tiger

D. 都不是

如果发现我写的有问题,评论区见,万分感谢~