2018-03-06 07:12:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 前言
|
|
|
|
|
|
2018-03-06 14:22:25 +00:00
|
|
|
|
### 面向对象的三大特性
|
|
|
|
|
|
|
|
|
|
- 封装
|
|
|
|
|
|
|
|
|
|
- 继承
|
|
|
|
|
|
|
|
|
|
- 多态
|
|
|
|
|
|
|
|
|
|
### 原型链的知识
|
|
|
|
|
|
|
|
|
|
|
2018-03-06 07:12:07 +00:00
|
|
|
|
原型链是面向对象的基础,是非常重要的部分。有以下几种知识:
|
|
|
|
|
|
|
|
|
|
- 创建对象有几种方法
|
|
|
|
|
|
|
|
|
|
- 原型、构造函数、实例、原型链
|
|
|
|
|
|
|
|
|
|
- `instanceof`的原理
|
|
|
|
|
|
|
|
|
|
- new 运算符
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-03-06 14:22:25 +00:00
|
|
|
|
## 创建对象有几种方法
|
|
|
|
|
|
|
|
|
|
### 方式一:字面量
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
var obj11 = {name: 'smyh'};
|
|
|
|
|
var obj12 = new Object(name: `smyh`);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面的两种写法是一样的。因为,第一种写法,`obj11`会指向`Object`。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 方式二:通过构造函数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
var M = function (name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
var obj3 = new M('smyhvae');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 方法三:Object.create
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
var p = {name:'smyhvae'};
|
|
|
|
|
var obj3 = Object.create(p);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
第三种方法,很少有人能说出来。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 原型、构造函数、实例,以及原型链
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20180306_1538.png
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PS:任何一个函数,如果在前面加了new,那就是构造函数。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 原型、构造函数、实例三者之间的关系
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20180306_2107.png
|
|
|
|
|
|
|
|
|
|
- 1、构造函数通过 new 生成实例
|
|
|
|
|
|
|
|
|
|
- 2、构造函数也是函数,构造函数的`prototype`指向原型。(所有的函数有`prototype`属性,但实例没有 `prototype`属性)
|
|
|
|
|
|
|
|
|
|
- 3、原型对象中有 constructor,指向该原型的构造函数。
|
|
|
|
|
|
|
|
|
|
上面的三行,代码演示:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
var Foo = function (name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fn = new Foo('smyhvae');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面的代码中,`Foo.prototype.constructor === Foo`的结果是`true`:
|
|
|
|
|
|
|
|
|
|
20180306_2120.png
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 4、实例的`_proto_`指向原型。也就是说,`Foo._proto_ === M.prototype`。
|
|
|
|
|
|
|
|
|
|
声明:所有的**引用类型**(数组、对象、函数)都有`_proto_`这个属性。
|
|
|
|
|
|
|
|
|
|
`Foo._proto_ === Function.prototype`的结果为true,说明Foo这个普通的函数,是Function构造函数的一个实例。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 原型链
|
|
|
|
|
|
|
|
|
|
**原型链的基本原理**:任何一个**实例**,通过原型链,找到它上面的**原型**,该原型对象中的方法和属性,可以被所有的原型实例共享。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object是原型链的顶端。
|
|
|
|
|
|
|
|
|
|
原型可以起到继承的作用。原型里的方法都可以被不同的实例共享:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
//给Foo的原型添加 say 函数
|
|
|
|
|
Foo.prototype.say = function () {
|
|
|
|
|
console.log('');
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**原型链的关键**:在访问一个实例的时候,如果实例本身没找到此方法或属性,就往原型上找。如果还是找不到,继续往上一级的原型上找。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## `instanceof`的原理
|
|
|
|
|
|
|
|
|
|
20180306_2209.png
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`instanceof`的**作用**:用于判断**引用类型**属于哪个**构造函数**。
|
|
|
|
|
|
|
|
|
|
`instanceof`的**原理**:判断实例对象的`_proto_`属性,和构造函数的`prototype`属性,是否指向同一个地址。
|
|
|
|
|
|
|
|
|
|
**注意**:
|
|
|
|
|
|
|
|
|
|
(1)虽然说,实例是由构造函数 new 出来的,但是实例的`_proto_`属性引用的是构造函数的`prototype`。实例的`_proto_`属性与构造函数本身无关。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(2)原型的上面可能还有原型,以此类推往上走。这条链上, instanceof 的返回结果也是 true。
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-03-06 07:12:07 +00:00
|
|
|
|
|