## 构造函数 原型 实例
> 每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针。
如果试图引用对象(实例instance)的某个属性,会首先在对象内部寻找该属性,如果查找不到,则会在该对象的原型(instance.__proto__)(下划线咋没了。。)里继续查找这个属性。
我们把这种搜索过程中,实例与原型的构成链条称作原型链。
![](https://user-gold-cdn.xitu.io/2017/4/21/9609b9a345af595208b73b505ad167a6.png?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)
## prototype 与__proto__
prototype 是只有函数才有的一个属性,指向函数的原型。
__proto__是对象的内部属性, 它指向构造器的原型, 对象依赖它进行原型链查询,instanceof 也是依赖它来判断是否继承关系.任何对象都有。
看一个例子:
~~~
function Person(name) {
this.name = name;
}
var p1 = new Person('louis');
console.log(Person.prototype); //Person原型 {constructor: Person(name),__proto__: Object}
console.log(p1.prototype); //undefined
console.log(Person.__proto__); //空函数, function(){}
console.log(p1.__proto__ === Person.prototype); //true
~~~
从这里我们注意到一个问题,
~~~
Person.__proto__ === Function.prototype // true
~~~
就是说可以说一般的构造器,都是继承于Function.prototype的。
那么Function.prototype是干什么的呢。
## Function.prototype
~~~
console.log(typeof Function.prototype) // "function"
console.log(Function.prototype.__proto__ === Object.prototype) // true
~~~
## instanceof
> instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
~~~
[] instanceof Object // true
[] instanceof Array // true
~~~
## isPrototypeOf()
> isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
~~~
Object.prototype.isPrototypeOf([]) // true
Array.prototype.isPrototypeOf([]) // true
~~~
## 继承
#### es5的继承方式
只能继承父类实例的属性和方法,不能继承原型上的属性和方法。
~~~
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
~~~
**组合继承**
调用了两次父类构造函数,生成了两份实例
~~~
function SuperType() {
this.name = 'superType';
@@ -73,6 +89,20 @@ var instance2 = new SubType('hx');
console.log(instance2.colors); // ["red", "blue"]
~~~
重点在于inheritPrototype函数
**寄生组合继承**
~~~
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
~~~
#### es6的继承方式
~~~
class superType {
constructor (name) {
this.name = name;
}
sayname() {
console.log(this.name);
}
}
class subType extends superType{
constructor (name) {
super(name);
}
getname() {
super.sayname(this.name);
}
}
let obj = new subType('sky');
obj.getname(); // 'sky'
~~~
## getPrototypeOf setPrototypeOf
getPrototypeOf(obj):返回给定对象的原型
Object.setPrototypeOf(obj, prototype):分别为要设定的对象以及要设定原型为。
## 遇到的题
1. 关于f可以有哪个属性的问题
~~~
var F = function () {
}
Object.prototype.a = function () {}
Function.prototype.b = function () {}
var f = new F();
~~~
我们可以通过这段代码发现:
~~~
console.log(f.__proto__ === F.prototype);
console.log(F.prototype.__proto__ === Object.prototype);
console.log(F.__proto__ === Function.prototype);
~~~
f的继承链应是从
~~~
f.__proto__ --->F.prototype.__proto__ ---> Object.prototype
~~~
所以可以取到a 取不到b。
- html
- 冒泡/捕获/委托
- 前端路由
- Dom
- 创建节点API
- 页面修改型API
- 节点查询型API
- 节点关系型API
- 元素属性API
- DOM事件
- classList
- 性能优化
- 节流防抖
- localStorage sessionStorage
- BOM
- meta
- data属性
- js实现拖拽
- html5
- 关于meta
- 轮播图
- js实现拖放
- 电话号inputFormater
- js
- es6
- promise
- iterator
- generator
- async
- proxy
- Set
- Map
- Object的扩展
- String
- Iterator
- Symbol
- 解构赋值
- 函数式编程
- module
- 基本数据类型
- 数组相关codings
- for of/for in
- this
- call bind apply
- 闭包
- 作用域
- prototype与继承
- 深浅拷贝
- setTimeOut/setInterval
- 垃圾处理机制
- 设计模式
- 观察者模式
- 单例模式
- 策略模式
- RegExp
- with
- 其他玩意
- Error/Stack Trace
- 面向对象
- css
- 回流重绘
- %取值
- 属性继承/属性优先级
- flex
- BFC
- 盒模型
- 设置css的方法
- 定位机制
- 块级/行内元素
- hack和一些别的玩意
- css动画
- 几个布局
- 画图形
- css3
- animation对比transform
- 点击不同图片区域跳转不同
- css选择器性能问题
- vh rem em
- css选择器
- 伪类伪元素
- css匹配原理
- 数据结构与算法
- 数据结构
- 树
- 链表
- 栈和队列
- 排序
- 归并排序
- 插入排序
- 选择排序
- 冒泡排序
- 快速排序
- 递归
- 回溯法
- 搜索算法
- 动态规划
- http
- 跨域问题
- CORS
- GET/POST
- ajax
- ajax上传文件
- http缓存
- https
- TCP/UDP
- cookie/session
- http2.0
- spdy
- websocket
- React
- redux
- 生命周期
- 虚拟dom与diff
- 双向数据绑定
- mvvm
- setState
- contextApi props reudx
- 高阶组件
- react-redux
- Fiber
- react-router
- 受控/非受控组件
- 待整理
- webpack
- loader实现
- 前端安全
- 移动端适配
- Vue
- 传值
- 其他