前言
说明:内容总结自王福朋等多位的文章
我感觉理解原型的核心就是这张图片;
理解构造函数和原型对象和实例的三角恋
构造函数通过new生成实例,实例通过.constructor找到构造函数,构造函数通过.prototype找到其的原型对象(默认值就是一个对象,含有一个constructor的属性指向构造函数),原型对象通过.constructor属性指向构造函数;另外一条就是实例通过__proto__找到原型对象(隐藏属性即暗恋);
原型链
原型链就是当你访问对象的属性时,如果不存在这个属性就会向其原型对象找这个属性,直至Object.prototype.__proto__都找不到就返回null;万物都是对象,所以对象的原型对象就是原型链的终点;
原型继承
主要介绍的是基于原型关系的继承写法,首先继承主要的目的就是想让子代能够使用父代的东西,感觉就是像子承父业,既然是继承,子与父必然是同一个类型,这边就先讨论构造函数;原型中原型链就满足了继承的所需,所以原型继承就是将两个构造函数组成原型链;
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log(100000);
};
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
//如果要使用父构造函数的构造就加Father.call(this, uname, age);
Father.call(this, uname, age);
this.score = score;
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数 目的是形成完美的原型对象链,否则Son.prototype.constructor指向的就是Father
Son.prototype.constructor = Son;
// 这个是子构造函数专门的方法
Son.prototype.exam = function() {
console.log('孩子要考试');
}
var son = new Son('洵回', 18, 100);
console.log(son);
son因为Father.call(this, uname, age)在构造的时候能够使用父的相关构造;Son.prototype = new Father();因为这个son可以使用父的.money,为了避免调用等问题在增加Son.prototype.constructor = Son;详情看阮一峰的相关内容;
理解 Object 和 Function 这个闭环的关系
我感觉Object和Function的关系有点类似鸡和蛋的关系,主要就是 Object.__proto__ 指向 Function.prototype,而 Function.prototype.__proto__指向的是Object.prototype;不过从结果来看prototype,Function构建出来的实例都具有prototype这个属性,而Object构建出来的实例都有 __proto__这个属性,JS中又基本都是对象,所以基本都有__proto__这个属性;
这就解释了我之前的一个疑惑,为什么Object构建出来的实例不具有prototype,而function构建出来都具有prototype;
理解new的操作
new过程中会新建对象,此对象会继承构造器的原型与原型上的属性,最后它会被作为实例返回这样一个过程;
- 以构造器的prototype属性为原型,创建新对象;
- 将this(也就是上一句中的新对象)和调用参数传给构造器,执行;
- 如果构造器没有手动返回对象,则返回第一步创建的新对象,如果有,则舍弃掉第一步创建的新对象,返回手动return的对象。
可以这样写相关的代码
//自己定义的new方法
let newMethod = function (Parent, ...rest) {
// 1.以构造器的prototype属性为原型,创建新对象;
let child = Object.create(Parent.prototype);
// 2.将this和调用参数传给构造器执行
let result = Parent.apply(child, rest);
// 3.如果构造器没有手动返回对象,则返回第一步的对象
return typeof result === 'object' ? result : child;
};
或者是按照你不知道的js上说得:
new调用:
- 1)创建或构造一个新的对象,
- 2)新对象被执行【【原型】】连接
- 3)新对象会绑定到函数调用的this
- 4)若函数没有返回其他对象,则new表达式中函数会自动返回这个新对象
也就是
function createnew(person,...rest){
let obj = new Obejct();
obj.__proto__=person.prototype;
let result = person.call(obj,...rest);
return typeof result ==='object'? result : obj
}
以上就是我的总结,有问题希望指出让我学习学习;