diff --git a/06-前端基础/05-原型链.md b/06-前端基础/05-原型链.md deleted file mode 100644 index 90b544f..0000000 --- a/06-前端基础/05-原型链.md +++ /dev/null @@ -1,235 +0,0 @@ - - -## 前言 - -### 面向对象的三大特性 - -- 封装 - -- 继承 - -- 多态 - -### 原型链的知识 - - -原型链是面向对象的基础,是非常重要的部分。有以下几种知识: - -- 创建对象有几种方法 - -- 原型、构造函数、实例、原型链 - -- `instanceof`的原理 - -- new 运算符 - - - -## 创建对象有几种方法 - -### 方式一:字面量 - -```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 - - - - - -``` - - - - - - diff --git a/06-前端基础/05-原型链总结.md b/06-前端基础/05-原型链总结.md new file mode 100644 index 0000000..cadeb6b --- /dev/null +++ b/06-前端基础/05-原型链总结.md @@ -0,0 +1,276 @@ + + +## 前言 + +### 面向对象的三大特性 + +- 封装 + +- 继承 + +- 多态 + +### 原型链的知识 + + +原型链是面向对象的基础,是非常重要的部分。有以下几种知识: + +- 创建对象有几种方法 + +- 原型、构造函数、实例、原型链 + +- `instanceof`的原理 + +- new 运算符 + + + +## 创建对象有几种方法 + +### 方式一:字面量 + +```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); //此方法创建的对象,是用原型链连接的 +``` + +第三种方法,很少有人能说出来。这种方式里,obj3是实例,p是obj3的原型(name是p原型里的属性),构造函数是`Objecet` 。 + + +20180306_1633.png + + +## 原型、构造函数、实例,以及原型链 + + +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**:在原型链上,原型的上面可能还会有原型,以此类推往上走,继续找`__proto__`属性。这条链上如果能找到, instanceof 的返回结果也是 true。 + +比如说: + +- `foo instance of Foo`的结果为true,因为`foo.__proto__ === M.prototype`为true。 + +- **`foo instance of Objecet`的结果也为true**,因为`Foo.prototype.__proto__ === Object.prototype`为true。 + + +但我们不能轻易的说:`foo 一定是 由Object创建的实例`。这句话是错误的。我们来看下一个问题就明白了。 + +### 分析一个问题 + +**问题:**已知A继承了B,B继承了C。怎么判断 a 是A直接生成的实例,还是B直接生成的实例呢?还是C直接生成的实例呢? + +分析:这就要用到原型的`constructor`属性了。 + +- `foo.__proto__.constructor === M`的结果为true,但是 `foo.__proto__.constructor === Object`的结果为false。 + +所以,用 consturctor判断就比用 instanceof判断,更为严谨。 + + +## new 运算符 + +new 运算符的原理如下: + +(1)创建一个**新的空对象**,此空对象继承自`Foo.prototype`,也就是继承自构造函数的原型。 + +(2)构造函数被执行。执行的时候,传入相应的参数(如果没有参数就不用传),同时 this 指向这个新实例。 + +(3)如果构造函数返回的是“对象”,那么这个对象会取代整个 new 出来的结果。如果构造函数没有创建对象,那么 new 出来的结果为步骤(1)创建的对象。 + + + +## 类继承和原型继承的区别 + + + + + + +```javascript + + + + + +``` + + + + + + + + + +```javascript + + + + + +``` + + + + + + + + + +```javascript + + + + + +``` + + + + + + + + + +```javascript + + + + + +``` + + + + + + + + + +```javascript + + + + + +``` + + + + + + + + + +```javascript + + + + + +``` + + + + + + diff --git a/06-前端基础/21-推荐文章.md b/06-前端基础/21-推荐文章.md new file mode 100644 index 0000000..9996b2b --- /dev/null +++ b/06-前端基础/21-推荐文章.md @@ -0,0 +1,21 @@ + + +## 征服JavaScript面试系列 | 众城翻译 + + +- [征服 JavaScript 面试:什么是闭包?](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-closure) + +- [征服 JavaScript 面试:什么是函数组合](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-function-composition) + +- [征服JavaScript面试系列:类继承和原型继承的区别](http://www.zcfy.cc/article/master-the-javascript-interview-what-s-the-difference-between-class-amp-prototypal-inheritance-2185.html) + +- [征服 JavaScript 面试:什么是纯函数](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-pure-function-2186.html) + +- [征服 JavaScript 面试: 什么是函数式编程?](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-functional-programming-2221.html) + +- [征服 JavaScript 面试: 什么是 Promise?](http://www.zcfy.cc/article/master-the-javascript-interview-what-is-a-promise) + + + + +