前言
对于原型的理解在这次复习的时候才发现之前的理解是不够透彻,甚至还有一些点是错误的,所以今天翻看了很多很好的文章彻底通透了一下,最后面在结合例题一起看一下,自己也做一个总结笔记。
原型一提及到脑海中的点莫过于这些:
-
prototype (原型)
-
__proto__(原型链) -
构造函数
-
new
-
this
-
call、apply
就结合案例说一下上面各个点(概念那些的这边就不说了,千篇一律)。
案例讲解
很感谢与掘金一个博主分享的一篇文章,建议大家先看一下,因为很多提及到的都是根据这篇文章而过来的,是对JS对象及方法的整体架构的一个讲解文章链接,想了一想不知道从哪个点开始讲解,直接从构造函数案例开始吧。
function Person(appearance, age) {
this.appearance = appearance;
this.age = age;
}
Person.prototype = {
father: "爸爸"
}
let person = new Person('handsome', 18);
let person1 = new Person('handsome', 18);
我们就直接针对这个案例开始撸。
原型
当我们创建实例对象时new所做的事情就是开辟一个新的堆然后定义一个隐式的this对象我们看内容,既然是开辟新堆那这两个实例虽然参数相同但显然不是一个东西。打个很简单的比方,我们两个实例是一对双胞胎,外貌帅年龄相同,旁人看起来就是一模一样,但事实上不是一个人,但有着相同的父亲(通过__proto__找到)。
// person实例创建
console.log(person === person1) //false
console.log(person.__proto__ === person1.__proto__) //true
person = Person('handsome', 18) {
var this = {
__proto__: Person.prototype
name: "handsome",
age: 18
}
}
// 最后返回this对象
__proto__小编觉得当做一个连接工具去理解这样会比较好去想,但是我们不能理解为__proto__就是去找自己的原型,根据上面所说那么我们就可以知道了。
person.__proto__ = {
father: "爸爸"
}
call
然后我们在看一个call的特殊案例
function fn1() {
console.log(1);
this.num = 111;
this.sayHey = function() {
console.log("say hey.");
}
}
function fn2() {
console.log(2);
this.num = 222;
this.sayHello = function() {
console.log("say hello.");
}
}
fn1.call(fn2); // 1
fn1(); // 1
fn1.num; // undefined
fn2(); // 2
console.log(fn2.num); // 111
// fn2.sayHello();
fn2.sayHey(); //say hey.
我们知道call方法改变this指向,this的作用域这边小编之前博客写,很容易知道这两个方法实际上没有任何”有意义“的声明,this在执行函数后都是指向windows的,但在call方法的作用下使得fn1的this指向fn2。
fn1.call(fn2); // 1 我们可以看到这一步不仅改变了this指向还执行了fn1函数,那么fn1执行相当于
fn1() {
console.log(1);
fn2.num = 111;
fn2.sayHey = function() {
console.log("say hey.");
}
}
所以得到以上的输出结果。
总结
其实原型主要理解还是JS世间万物诞生记,小编只是借用了几个案例去进行了一下分析去更好的理解。原型就此终止了咯。