javascript中的__proto__ && prototype

原创
2016/04/03 14:36
阅读数 71

说到__protot__ 跟 prototype 就要说到new了

首先要说的是,new 一个对象的整个过程中,产生的对象有3个,例如下面这段代码中

let Human = function(name,age,gender){
    this.name   = name;
    this.age    = age;
    this.gender = gender;
};
console.log(Human.prototype.constructor === Human);  //true
let people = new Human('rainn',25,'male');
console.log(people.__proto__ === Human.prototype);  //true

在创建Human的时候 系统会为其创建了一个原型对象Human prototype,Human prototype中会创建一个constructor属性指向Human,而Human 中的prototype又会指向Human prototype.

再看看new 的过程,. 大概可以分成3个步骤 : 声明变量people , 将people的__proto__属性指向 Human prototype,然后执行Human.call(people),即执行constructor.

Human.prototype 是指向的Human prototype这个对象的,由people.__proto__===Human.prototype 就可以证明上述new 过程中的第二点.

__proto__是什么?简单来说,就是对象内部初始化一个属性,就是__proto__,这个属性指向的就是它的原型,当我们访问对象内部的一个属性或方法时,当对象内部不存在该属性或者方法时,就会去原型中寻找需要的属性或者方法,而它的原型又有原型,不存在还会继续沿着原型找下去,这就是原型链的概念.

比如上述代码中,Human中只有3个属性,并没有say方法,而需要用到方法时,可以采用两种方式;

let Human = function(name,age,gender){
    this.name   = name;
    this.age    = age;
    this.gender = gender;
    this.say    = function(){
        return 'hello i'm ${this.name}. I'm ${this.age} and I'm a ${this.gender}';
    }
};
let people = new Human('rainn',25,'big boy');
alert(people.say());   //hello i'm rainn. I'm 25 and I'm a big boy;

这种方式可以实现添加say方法,但是如果需要new多个对象的时候,就会占用更多的内存,所以可以采取在原型链中添加方法

let Human = function(name,age,gender){
    this.name   = name;
    this.age    = age;
    this.gender = gender;
};
/*
此处仅证明当people原型Human中没有say方法而Human原型中有时,也可以调用say方法,与下面代码不同时写入
Human.prototype.__proto__.say = function(){
    return `hello i'm ${this.name}. I'm ${this.age} and I'm a ${this.gender}`;
}
*/
Human.prototype.say = function(){
    return `hello i'm ${this.name}. I'm ${this.age} and I'm a ${this.gender}`;
}
let people = new Human('rainn',25,'big boy');
alert(people.say());   //hello i'm rainn. I'm 25 and I'm a big boy;

可以看到,当people中不存在say方法时,会向__proto__指向的Human prototype中寻找,如果没有,会继续向上一层的__proto__中寻找,此时say方法时存在原型中,所以即使new 更多的对象,也不会占用额外的内存去保存这些方法.

可以看到,原型链的实现在于__proto__,在上面例子中,people.__proto__与Human.prototype 指向的都是Human prototype,而在添加原型属性或者方法时,才会采用Human.prototype,因为 在原型中添加属性或者方法时,多数情况是在new 对对象之前,这个时候就通过people.__proto__添加所需要的属性或方法.


以上内容本人见解,如有错误,望指出共进步,谢谢


展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部