原型和原型链
原型概念
每一个js对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型继承属性和方法
原型链概念
每个实例对象(object)都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(__proto__),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
原理
1. prototype
1 | function Person() { |
函数的prototype属性指向一个对象, 这个对象正是调用该构造函数而创建的实例原型, 也就是person1 和 person2
2. __proto__
1 | function Person() { |
每一个js对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。
3. constructor
1 | function Person() { |
每个原型都有一个 constructor 属性指向关联的构造函数
4. 实例和原型
1 | // 构造函数 |
但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 fanky
但是万一还没有找到呢?原型的原型又是什么呢?
5. 原型的原型
1 | let obj = new Object(); |
其实原型对象就是通过 Object 构造函数生成的,结合之前所讲,实例的 __proto__ 指向构造函数的 prototype
6. 原型链
那 Object.prototype 的原型呢:1
console.log(Object.prototype.__proto__ === null) // true
图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线
7. hasOwnProperty
在原型链上查询属性比较耗时,对性能有影响,试图访问不存在的属性时会遍历整个原型链。1
2
3
4
5
6
7const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
作用
继承属性
1 | let f = function () { |
继承方法
1 | var o = { |
闭包
概念
- 闭包就可以在全局函数里面操作另一个作用域的局部变量
- 形成步骤:
a. 外层函数嵌套内层函数
b. 内层函数使用外层函数的局部变量
c. 把内层函数作为外层函数的返回值
作用
1. 封装私有变量/模拟模块化
1 | function create_counter(initial) { |
2. 做缓存
数字累加
3. 实现代码块
1 | for (var i = 0; i < 5; i++) { |