构造函数就是普通函数,为了和其余函数区别,第一个字母大写。
特色:node
1.内部使用this表示 实例对象。 2. 生成对象用new关键字
const Anim = function (name) { this.name = name; } const cat = new Anim('cat');
内存图:浏览器
log验证:函数
console.log(cat.__proto__);// Anim{} console.log(Anim.prototype);//Anim{} console.log(Anim.prototype === cat.__proto__);// true
在node环境中Anim.prototype输出的是Anim{},而在浏览器环境输出的更明白一些
截图测试
node环境仍是有些问题的,建议不要在node环境测试。this
console.log(cat.__proto__);// Anim的prototype,含constructor的对象 console.log(cat.__proto__.__proto__);//Object的prototype,含constructor console.log(cat.__proto__.__proto__.__proto__);//null console.log(cat.__proto__);// Anim的prototype,含constructor的对象 console.log(cat.__proto__.__proto__);//Object的prototype,含constructor console.log(cat.__proto__.__proto__.__proto__);//null console.log(Anim.__proto__);// Function的prototype,一个含constructor的对象 console.log(Anim.__proto__.__proto__);// Object的prototype,含constructor的对象 console.log(Anim.__proto__.__proto__.__proto__);// null
Object.getPrototypeOf(obj) 获取对象obj的原型对象 至关于obj.__proto__,只是__开头的是内部属性,不建议使用,推荐使用Object.getPrototypeOf()spa
console.log(cat.__proto__);// Anim{} console.log(Object.getPrototypeOf(cat));// Anim{} console.log(Anim.__proto__); console.log(Object.getPrototypeOf(Anim));// [Function]
原型对象prototype对象有一个constructor属性,指向构造函数对象,而构造函数对象有个prototype属性指向原型对象。prototype
console.log(Anim.prototype.constructor === Anim);// true
由于constructor在原型对象上,因此全部的实例对象都有constructor属性,并且都等于Anim.cat自己没有constructor属性,constructor是其原型链上的属性。code
console.log(cat.constructor === Anim.prototype.constructor);// true console.log(cat.constructor === Anim);// true
function Cat(){} function Dog(){} function isDog(obj){ return obj.constructor === Dog; } const black = new Cat(); const white = new Dog(); console.log(isDog(black));// false console.log(isDog(white));// true
const yellow = new white.constructor(); console.log(isDog(yellow));// true
console.log(yellow instanceof Dog);
左侧是实例对象,右侧是构造函数。可能会想到原理是对象
yellow.constructor === Dog
除了使用constructor,还有Object.prototype.isPrototypeOf(),对象实例的isPrototypeOf方法,用来判断一个对象是不是另外一个对象的原型ip
const date = new Date(); console.log(date instanceof Date);// true console.log(date instanceof Object);// true console.log(Date.prototype.isPrototypeOf(date));// true console.log(Object.prototype.isPrototypeOf(date));// true
instanceof对整个原型链上的对象都有效,所以同一个实例对象,可能会对多个构造函数都返回true。
const a = { name:'aaaa', log:function(){ console.log(this.name); } }; const b = Object.create(a); b.name = 'bbb'; const c = Object.create(b); c.name = 'ccc';
打印a,b,c
console.log(a.__proto__ === Object.prototype);// true console.log(b.__proto__ === a);// true console.log(c.__proto__ === b);// true
猜想create的过程
b.__proto__ = a;
若是建一条原型链,可使用create,只是没有构造函数,也不存在prototype。
字面量对象没有prototype属性,没法使用new关键字建立实例对象。
var o = { name:'michael', age:10, say:()=>{ console.log('hello'); } };