一、创建对象的三种方式
o1和o2为一种
var o1={name:'o1'};
console.log(o1);
var o2=new Object({name:'o2'});
console.log(o2);
var M=function (name) {
this.name=name
};
var o3=new M('o3');
console.log(o3);
var p={name:'p'};
var o4=Object.create(p);
console.log(o4);
二、构造函数、原型、实例、原型对象
普通函数new时本身变成构造函数
声明函数会自动增加prototype属性就是原型对象,也只有函数有prototype,对象是没有的,但是函数本身是一个实例,因此函数也有__proto__。
通过以下方式验证:
M构造函数.__proto===Function.prototype为true,可说明M构造函数是Function的一个实例。
原型对象的constructor属性指向构造函数
实例的__proto__指向构造函数的原型对象
原型链是针对构造函数的,构造函数生成实例后,实例的某个属性虽然未在实例定义,但是它会往构造函数的属性查找,这个结构为原型链
原型链的应用
instanceof判断实例对象的__proto__是不是引用同一个构造函数的prototype,o3 instanceof M值为true,M.prototype在原型链上也看作实例对象,可得到M.prototype.__proto__=Object.prototype
instanceof很难判断出实例到底是哪个构造函数生成的,可采用“原型对象的constructor属性指向构造函数”找出本来的构造函数,如o3.__proto__.constructor===M,返回true,constructor比起instanceof判断更为严谨
三、new 运算符
new后面跟的是构造函数,创建一个空的新对象,空对象继承构造函数的原型对象;
构造函数被执行,执行的时候传入相应参数,同时上下文this会被指定为这个新实例;
如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果,如果构造函数没有返回对象,那么new出来的结果为继承的原型对象;