Javascript原型、构造函数、实例的关系
1. 原型、构造函数、实例的关系
-
原型:
- 原型通过constructor指向构造函数,原型如果是自定义对象且没有明确将constructor指向构造函数,则原型的constructor指向函数的基类Function。
- 原型通过方法isPrototypeOf检查是否和实例之间有关系;
-
构造函数:
- 构造函数的prototype指向原型
- 因为构造函数和原型可以生成多个实例,所以它两者不关心其所对应的实例,没有直接获取其对应实例的途径。
- 构造函数通过
instanceof
查看和实例之间是否有关系。
-
实例
- 实例的__proto__检查指向其原型;
- 实例的constructor检查是否和构造函数有关系
- 实例通过
Object.getPrototypeOf(实例)
可以查看其原型是谁 - 实例和原型的constructor都明确的指向构造函数,但原型如果是自定义对象且没有明确将constructor指向构造函数,则原型的constructor指向函数的基类Function。
2. 实例化的过程
-
创建一个对象
-
创建__proto__属性指向构造函数的prototype属性,创建constructor属性指向自己的构造函数;
-
将构造函数的所有私有属性方法复制到自己身上;
以下为函数实现:function Move(name) { this.name = name this.say = function() { console.log('hello,say') } } Move.prototype.age = 23; let s = new Move('tt'); console.log(s); // new关键字的函数实现 function newFunc(fn,...rest) { let obj = {}; obj.constructor = fn; obj.__proto__ = fn.prototype; fn.call(obj,rest); return obj; } let newS = newFunc(Move, 'tt') console.log(newS)
3. 扩展
对象两两不相等,因为他们指针所对应的实际存储位置不一致,如果一致,也是相等的。
function Move() {}
let obj = {age: 23}
Move.prototype = obj;
var m = new Move()
console.log(Move.prototype === m.__proto__) // true
console.log(Move.prototype === obj) // true
console.log(m.__proto__ === obj) // true
console.log(obj.isPrototypeOf(m)) // true
console.log(Object.getPrototypeOf(m)) // { age: 23 }
console.log(m instanceof Move) // true