JS深入系列笔记
前言
这篇文章是我反复阅读冴羽大佬博客至少三遍后总结的,因为是笔记,
所以力求罗列知识点,没有给出探索过程,没有详细解释,
甚至略去一些认为是常识的知识点,供自己复习学习。
在很多群里看到前端新人问闭包,原型链,执行上下文等问题的时候,
都会不留余力地向他们推荐冴羽的博客,因为真的很易懂,很精炼。
是我初入前端基础知识学习第一个完整看完的博客。
下面给出原文链接:
冴羽的博客
1.深入原型到原型链
这一篇主要讲述了,构造函数、实例、实例原型三者的关系,以及原型链。
下面先从这三个名词开始讲解
function Person() { //构造函数
}
Person.prototype.name = 'Kevin'; // Person.prototype指向的对象就是实例原型
var person1 = new Person(); // person1实例对象
console.log(person1.name) // Kevin
其中Person()
就是构造函数,Person.prototype
代表的对象就是原型,person1
是实例对象(注意p的大小写)。
构造函数、实例、原型
构造函数:通过new
+ 函数名来实例化对象的函数就叫构造函数。任何函数都可以作为构造函数。定义时首字母大写(规范)。
new:和var
、return
、if
一样是JS的保留关键字,JS语法的一部分,内部调用了new Object
。
实例:面向对象的概念,抽象的具象到指定个体的产品。
实例原型:每一个JS对象在创建时都会与之关联一个对象,这个对象就是原型,每一个对象都会从原型”继承”属性。
prototype proto constructor
prototype:每个函数都具有的属性,且只有函数才有的属性。函数的prototype所指向的对象,就是该函数作为构造函数创建的实例的原型对象。
proto:每一个JavaScript对象(除nul)都具有的属性,这个属性会指向该对象的原型。
constructor:每一个原型都具有的属性,该属性指向关联这个原型的构造函数。
总结
// 函数 prototype => 原型
Person.prototype === person1.__proto__ //构造函数的prototype指向实例原型
// 实例 __proto__ => 原型
person1.__proto__ === Person.prototype //实例原型的两种表达方式
// 原型 constructor =>函数
Person.prototype.constructor === Person //实例原型的constructor指向构造函数
// 实例 Object.getPrototypeOf() => 原型
Object.getPrototypeOf(person1) === Person.prototype //冴羽大佬还教了一个从实例获取原型的方法,
//因为__proto__并非规范,而是浏览器自己实现的接口,真实来自于Object.prototype。
//是一个getter/setter,一个代理委托,可以理解为返回了Object.getPrototypeOf(obj)。
原型链
原型本身是对象,对象是Object()
创造出来的,所以默认情况下原型的原型是Object.prototype
,原型链的顶层是Object.prototype
,同时Object.prototype.__proto__ === null
读取实例属性时,如果找不到,就回去该对象原型中找,还找不到就找原型的原型,一直找到顶层为止。
总结
// 函数 prototype => 原型
Person.prototype === person1.__proto__ //构造函数的prototype指向实例原型
// 实例 __proto__ => 原型
person1.__proto__ === Person.prototype //实例原型的两种表达方式
// 实例 __proto__ __proto__ => Object.prototype
person1.__proto__.__proto__ === Object.prototype //原型的原型
// 原型 constructor =>函数
Person.prototype.constructor === Person //实例原型的constructor指向构造函数
// 知道原型链之后
person1.constructor === Person //当获取person1的constructor时,找了person1的原型上的constructor
person1.constructor === Person.prototype.constructor
“继承”:继承意味着赋值,而JS并不会赋值对象的属性,而是在对象之间创建指针,
再通过代理委托访问原型对象的属性与其叫继承,不如叫委托。