JS的原型对象与原型链

一、创建对象的方法

  1. 字面量
  2. 构造函数
  3. Object.create()
    // 第一种方式:字面量
    var o1 = {name: 'o1'}
    var o2 = new Object({name: 'o2'})
      // 第二种方式:构造函数
    var M = function (name) { this.name = name; }
    var o3 = new M('o3')
      // 第三种方式:Object.create
    var p = {name: 'p'}
    var o4 = Object.create(p)

二、prototype和__proto__的区别

JS的原型对象与原型链_第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() {}

__proto__属性指向谁?

__proto__属性的指向取决于对象创建的实现方式,以下三种方式:

JS的原型对象与原型链_第2张图片

/*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中的例外情况)

三、原型链

JS的原型对象与原型链_第3张图片

var M = function (name) { this.name = name; }
var o3 = new M('o3')
  •  实例就是对象,在本例中o3就是实例,M就是构造函数。
  • 实例通过new一个构造函数生成的。
  • 从上图中可以知道,实例的__protpo__指向的是原型对象。
  • 实例的构造函数的prototype也是指向的原型对象。 
  • 原型对象的construor指向的是构造函数。

由于__protpo__是任何对象都有的属性,而且js中万物皆对象,所以会形成一条由__protpo__链接起来的链条,简单理解就是原型组成的链,对象的__proto__它的是原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样可以一直通过__proto__想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。

当js引擎查找对象的属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链上逐级向上查找,直到找到为止,否则undefined。

JS的原型对象与原型链_第4张图片

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

JS的原型对象与原型链_第5张图片

你可能感兴趣的:(JavaScript)