- JS基础-原型和原型链【三座大山之一】
- JS基础-作用域和闭包【三座大山之二,待更新。。。】
- JS基础-异步【三座大山之三,待更新。。。】
1. 创建对象的几种方法
1.1 方式一:字面量
var o1 = {name : 'o1'}
var o11 = new Object({name : 'o1'})
1.2 方式二:构造函数
var M = function(){this.name = 'o2'}
var o2 = new M();
1.3 方式三:Object.create
var P = {name: 'o3'}
var o3 = Object.create(P)
2. 原型、构造函数、实例、原型链
2.1 原型
- 原型也是一个对象,通过原型可以实现对象的属性继承
- prototype就是调用构造函数所创建的那个实例对象的原型(proto)。
- 对象有"[[prototype]]"属性,函数对象有"prototype"属性,原型对象有"constructor"属性。
2.2 构造函数
- 用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写
2.3 实例
- 只要是对象就是一个实例
- 实例是类的具象化产品, 而对象是一个具有多种属性的内容结构。
- 实例都是对象,而对象不全是实例。
2.4 原型链
- 实例对象与原型之间的连接,叫做原型链。proto( 隐式连接 )
2.5 原型关系图示

2.6 代码讲解
var M = function(){this.name = 'o2'}
var o2 = new M();
console.log(o2)
console.log(M.prototype)
console.log(M.prototype.constructor === M)

2.7 prototype和__proto__的区别
- 构造函数(函数)才有
propotype 的,对象没有 propotype
- 只有实例对象有
__proto__的,函数既是函数又是对象
var M = function(){this.name = 'o2'}
var o2 = new M();
M.__proto__ === Function.prototype
3. instanceof 的原理
3.1 instanceof 运算符
- 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
判断函数FuncA是否是实例objA的构造函数的方法:
- instanceof:
objA instanceof FuncA === true
- 原理:obj.proto [_proto_加n个]=== FuncA.prototype
- 缺陷:这个方法不够准确,因为只要在同一条原型链上都会返回true
eg: obj._proto_._proto_ ===FuncA.prototype._proto_===Object.prototype
- constructor
obj._proto_.constructor === FuncA 一定准确
3.1 原理图示
- 是判断 实例对象.proto 和 构造函数.prototype是不是一个引用(即引用同一个地址)

var M = function(){this.name = 'o2'}
var o2 = new M();
o2 instanceof M
o2 instanceof Object
o2.__proto__ === M.prototype
M.__proto__ === Object.prototype
M.prototype.__proto__ === Object.prototype
o2.__proto__.constructor === M
o2.__proto__.constructor === Object
3.3 请实现一个instanceof,让以下代码可正常运行
- 考察instanceof的判断原理,instanceof主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。
- 因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false。
function instanceOf(left, right) {
let proto = left.__proto__
while(proto){
if(proto === right.prototype){
return true
}
proto = proto.__proto__
}
return false
}
class A{}
class B extends A {}
class C{}
const b = new B()
console.log(instanceOf(b,B))
console.log(instanceOf(b,A))
console.log(instanceOf(b,C))
new 运算符

- new构造函数的原理:
- 生成一个空对象(Object.create)
- 将空对象的__proto__指向构造函数的prototype
var o=Object.create(func.prototype)
- 执行构造函数,this上下文指向空对象
var k=func.call(o)
- 若构造函数返回的是对象,那么这个对象将取代原来的空对象;反之,返回之前的空对象
if(typeof k==='object'){
return k;
}else{
return o;
}
- 完整代码
var new2 = function(func) {
var o = Object.create(func.prototype)
var k = func.call(o)
if (typeof k==='object') {
return k
} else {
return o
}
}