对象
对象分为函数对象和普通对象:
- 函数对象:构造函数,
Function.prototype
- 普通对象:由构造函数实例化后的对象
原型对象
-
用于存放共同的属性和方法
-
构造函数通过
prototype
访问 -
实例化对象通过
__proto__
访问 -
原型对象有
constructor
属性,指向其构造函数- 如果修改了原型对象,一般会同时修改
constructor
属性,防止引用的时候出错。
- 如果修改了原型对象,一般会同时修改
-
原型对象的
__proto__
指向Object.prototype
相关方法
Object.prototype.isPrototypeOf()
Object.getPrototypeOf()
Object.setPrototypeOf(目标对象,原型对象)
Object.create(对象,属性描述对象)
- 创建一个新对象
- 将参数对象作为该新对象的原型对象,并返回
- 第二个参数:该新对象的属性描述对象
- 如果想单纯生成一个对象,参数应设为
null
构造函数
-
首字母大写
-
任何函数(除了箭头函数)都可以作为构造函数
-
用于实例化对象的函数叫构造函数
-
函数自己既是构造函数,又是实例化对象
fn.__proto__===Function.prototype //作为Function()实例化对象
原型链
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。
-
先有的
Object.prototype
,原型链的尽头是nullObject.prototype.__proto__===null
-
通过
Object.prototype
创建出Function.prototype
,Array.prototype
,Number.prototype
,RegExp.prototype
等多个原型对象所有原型对象都继承于Object.prototype
Array.prototype.__proto__===Object.prototype Number.prototype.__proto__===Object.prototype String.prototype.__proto__===Object.prototype Boolean.prototype.__proto__===Object.prototype Date.prototype.__proto__===Object.prototype RegExp.prototype.__proto__===Object.prototype Function.prototype.__proto__===Object.prototype
-
通过
Function.prototype
创建出Function()
,Object()
,Array()
等多个内置构造函数所有的构造函数都继承于Function.prototype
Array.__proto__===Function.prototype Number.__proto__===Function.prototype String.__proto__===Function.prototype Boolean.__proto__===Function.prototype Date.__proto__===Function.prototype RegExp.__proto__===Function.prototype Function.__proto__===Function.prototype Object.__proto__===Function.prototype
new原理
当构造函数实例化对象后,构造函数的 prototype
对象会自动挂载到实例对象上,作为其原型对象
【底层原理】
-
创建一个空对象,作为将要返回的对象实例
- 如果构造函数return的是一个对象,则返回该对象而不是空对象(相当于覆盖)
- 如果构造函数return其他类型,则忽视
obj={ id:'1', person:{ name:"bob" } } function deepClone(){ return obj } let a=new deepClone() //{ id: '1', person: { name: 'bob' } }
-
将这个空对象的
__proto__
,指向构造函数的prototype
a.__proto__===deepClone.prototype
-
改变函数内部的
this
指向,指向这个空对象 -
执行构造函数其余的内部代码
【代码实现】
function Person(name, age) {
this.name = name;
this.age = age;
// return {a:'haha'}
}
Person.prototype.show = function () {
console.log(this);
}
function _new() {
let args = Array.from(arguments);//将类数组转为数组
let constructor = args.shift();//提取构造函数,剩下的为参数
let obj = {};//创建空对象
obj.__proto__ = constructor.prototype;//空对象继承构造函数原型对象
let rs = constructor.apply(obj, args);//改变构造函数内部this指向
// 如果返回结果是对象,就直接返回,否则返回空对象
return (typeof rs === 'object' && rs != null) ? rs : obj;
}
let p = _new(Person, 'limign', 20);
console.log(p);//Person {name: 'limign', age: 20}