创建对象的3种方法
//方法一:
var o1 = {name: 'o1'};
var o11 = new Object({name: 'o11'});
//方法二:
var M = function () {
this.name = 'o2';
}
var o2 = new M();
//方法三:
var p = {name: 'o3'};
var o3 = Object.create(p);
new Object() 和 Object.create()区别:
{}等同于new Object(), 原型对象是Object.prototypeObject.create(null)没有原型Object.create({...})可以指定原型
原型链
看图说话:
- 一个函数f 被new f() 操作会成为构造函数;
- 构造函数有prototype属性(其实所有函数都有prototype属性)指向 原型对象;所以当我们给数组统一添加方法的时候,即给原型对象上添加方法:
Array.prototype.flatter = function(){}
所有数组的实例都可以使用flatter方法。
- 实例对象有__proto__属性,也是指向原型对象的;
- 原型对象有一个constructor属性指向构造函数;
- 原型对象也可以看成一个对象实例,也有__proto__属性,指向它的原型对象。
- 构造函数的原型对象的
__proto__会指向Object.prototype,Object.prototype.__proto__最终指向null。
function Person(name){
this.name = name;
}
let p = new Person("William");
console.log(Person.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
instanceof 实际是什么?
p instance Person; 其实看的是 p._proto_ 跟 Person.prototype 是否指向同一个对象。
手写 instanceof
function myinstanceof(L, R){
const t = L.__proto__;
if(t===null){
return false;
}
if(t===R.prototype){
return true;
}else{
return myinstanceof(t, R);
}
}
new操作运算符做了什么?
- 创建了一个对象o;
- 将对象o的__proto__指向 构造函数 的 prototype,即使得 o的__proto_指向 原型对象;
- 转换上下文到o对象执行构造函数体里面的逻辑,得到结果 result;
- 判断result 结果是否是 object 类型;如果是,返回 result; 如果不是返回 o 对象。
const create = function(fn, ...rest){
let o = {};
o.__proto__ = fn.prototype;
// 等价于
// let o = Object.create(fn.prototype);
let result = fn.apply(o, rest);
if(typeof result==='object'){
return result;
}else{
return o;
}
}
function Person(name, age) {
this.name = name;
this.age = age;
}
let p = create(Person, 'zs', 12);
console.log(p);
其中,o = Object.create(f), 相当于把o的原型对象指向 f。