JS 中的原型 -- prototype、__proto__ 以及原型链

原文:

1.深入理解javascript原型和闭包——prototype原型

2.三张图搞懂JavaScript的原型对象与原型链

 

打开浏览器控制台,任意定义一个对象,打印出来后,会发现有最后一定有一个默认属性 “__proto__”,这是 js 的设计思路,类似于 java 中的继承。

 

注意:在本章中严格区分函数对象

 

prototype 与 __proto__

1.区别

var a = {};
console.log(a.prototype);  //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype);  //b {}
console.log(b.__proto__);  //function() {}

 

2.__proto__ 指向谁?

 

/*1、字面量方式*/
var a = {};
console.log(a.__proto__);  //Object {}

console.log(a.__proto__ === a.constructor.prototype); //true

/*2、构造器方式*/
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}

console.log(a.__proto__ === a.constructor.prototype); //true

/*3、Object.create()方式*/
var a1 = {a:1}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1}

console.log(a.__proto__ === a.constructor.prototype); //false(此处即为图1中的例外情况)

 

 

3.原型链

var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null

 

 

 

prototype 属性

这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做 constructor 的属性,指向这个函数本身。如下图:

原型既然作为对象,属性的集合,不可能就只弄个constructor来玩玩,肯定可以自定义的增加许多属性。例如 Object 这个函数,该函数的prototype里面,就有好几个其他属性。

 

以上是 Object 的原型示意。

 

那么,我们自己定义的函数/对象中,可不可以进行自定义内? 答案: 可以。

function Fn() { }

Fn.prototype.name = '王福朋';
Fn.prototype.getYear = function () {
     return 1988;
};

 

 

这样做的意义在哪?

function Fn() { }

Fn.prototype.name = '王福朋';
Fn.prototype.getYear = function () {
    return 1988;
};

var fn = new Fn();
console.log(fn.name);    // 王福朋
console.log(fn.getYear());  // 1988

首先,定义了个空的 Fn 函数;

接着,自定义 Fn.prototype 属性;

其次,fn 对象是从 Fn 函数中 new 出来的;

 

 

因为每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象函数的prototype(注意区分对象和函数)。即:fn.__proto__ === Fn.prototype

 

结论:每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象函数的prototype(注意区分对象和函数)。

posted @ 2018-08-04 15:28  shiweiqianju  阅读(476)  评论(0编辑  收藏  举报