一、创建对象的方法
- 字面量
- 构造函数
- 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__的区别
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__属性的指向取决于对象创建的实现方式,以下三种方式:
/*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中的例外情况)
三、原型链
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。
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