### [[Prototype]]
当你试图引用对象的时候,就会触发[[Get]]操作,当对象本身不含有该属性时就会查找[[Prototype]]链,如果链没有找到该属性并且链不为空,则会继续顺延[[Prototype]]继续查找下去。
for...in...会枚举出所有可enumerable的属性,包括原型链上的。
而...in...操作符来检查属性时也会查找原型链(无论属性是否可枚举)。
#### 屏蔽
所谓屏蔽,就是原型链上有foo属性,而对象本身没有该属性,当执行obj.foo操作时会为该对象添加foo属性,原型链的foo会被遮蔽。
1. 如果原型链上存在foo属性,且可读,则obj.foo操作会直接在obj上添加foo属性。
2. 如果原型链上存在foo属性,且不可读,则该操作会失败,foo属性不会被添加。
3. 如果原型链上存在foo属性,且设置了setter,则该操作会触发setter。foo不会被添加,也不会重新定义这个setter。
隐示屏蔽
```
var obj1 = {a: 2};
var obj2 = Object.create(obj1);
obj1.a; //2
obj2.a; //2
obj2.hasOwnProperty('a'); //false
obj2.a++;
obj1.a; //2
obj2.a; //3
obj2.hasOwnProperty('a'); //true
//obj2.a++实际上就是obj2.a = obj2.a + 1,创建了一个新的自身的a,屏蔽了原型的
```
### 类
new操作符并不是创建新的实例,而是让“新实例”的原型指向函数的prototype。
```
function Foo() {};
var a = new Foo();
Object.getPrototypeOf(a) === Foo.proptotype; //true
```
#### 构造函数与调用
Foo与其他函数没有任何区别,当使用new调用时会执行“构造函数调用”。
```
function Foo() {console.log(123)};
var a = new Foo();
//123
console.log(a); //{}
```
所以,js中的构造函数,其实就是带new的普通函数罢了。
回顾构造函数,.constructor并不是代表“由谁构造”,它只是委托。
```
//函数自带constructor
Foo.prototype.constructor == Foo; //true
var a = new Foo();
//a没有constructor,此时会查找原型链,Foo的原型上有constructor,返回
a.constructor === Foo; //true
Foo.prototype = {};
var b = new Foo();
//现在,Foo.prototype已经没有了constructor,只能继续向上查找,直到Object(Object.prototype.constructor)
b.constructor === Foo; //false
b.constructor === Object; //true
```
### 原型继承
```
//创建一个新的Bar.prototype对象并指向Foo.prototype,旧的Bar.prototype会被抛弃。修改Bar.prototype不会影响Foo.prototype
Bar.prototype = Object.create(Foo.prototype);
//直接指向Foo.prototype,修改Bar.prototype会影响Foo.prototype
Bar.prototype = Foo.prototype;
//另一种实用的方法,es6的api,直接修改现有的Bar.prototype并且不影响Foo.prototype
Object.setPrototypeOf(Bar.prototype, Foo.prototype)
```
`var b = Object.create(a)`,如果a是对象的话会创建新的b.prototype并将其指向a,如果a是函数的话则b.prototype将会指向a.prototype。
```
function A(){this.name = 1};
var b = Object.create(A); //b是一个函数
b.prototype.constructor === A; //true
var A = {a: 1};
var b = Object.create(A);
b.prototype; //undefined
b.__proto__ === A; //true
```
- 你不知道的JS上
- 第一部分 第三章 函数作用域和块作用域
- 第一部分 第四章 提升
- 第一部分 第五章 闭包
- 第二部分 第一章 关于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 对象
- 第二部分 第五章 原型
- 第二部分 第六章 行为委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函数
- 第一部分 第四章 强制类型转换
- 第一部分 第五章 语法
- 第二部分 第一章 异步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 总结
- 第二部分 第二章 语法
- 第二部分 第三章 代码组织
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元编程
- 第二部分 第八章 ES6之后