一日客语:中文:圆 客语: 眼ienˇ
昨天讲述为啥修改了Cat原型後使用Object.getPrototypeOf(niki).constructor
为何是印出 Object 呢
一开始 Object.getPrototypeOf(nini).constructor
明明是Cat为何原型有这种差异呢
就继续看下去~
function Cat() {
this.eat = () => 'apple';
}
const nini = new Cat();
Cat.prototype.sleep = 'sleep';
console.log(Object.getPrototypeOf(nini)); //{ sleep: 'sleep' }
//原型变动
//新物件改掉Cat原型
Cat.prototype = {
go: function () {
return 'go';
},
};
const niki = new Cat();
console.log(Object.getPrototypeOf(niki)); //{ go: [Function: go] }
Object.getPrototypeOf(niki).constructor//Object
instanceof :niki instanceof Cat
判断实例是不是透过建构器函式建立的
constructor:实例.constructor
可以找到创建实例的建构函式
wendy instanceof Wendy
运作方式:
会先查Wendy的原型
此原型是否出现在wendy的原型链上
function Wendy() {}
function Ann() {}
Ann.prototype = new Wendy(); //目前 Ann.prototype ={}
const smallAnn = new Ann();
console.log(smallAnn instanceof Ann);//true
//Ann的原型是否出现在smallAnn上
console.log(smallAnn instanceof Wendy);//true
//Wendy的原型是否出现在smallAnn上
实例.constructor:实例的原始函式参照(物件的起源)
要注意一件事情:
let a = new Apple()
什麽property都没有只剩下[[prototype]]
点开[[prototype]]
,从这区开始(记得这里是物件喔)会是Apple.prototype
此时就要想想,prototype是建构函式才会有,就要思考来自哪个函式就会是他的constructor
所以a.constructor
是来自Apple的prototype
这个prototype是因为Apple function 才有的,所以constructor是Apple
(忍耐一下这边是需要停下来好好思考的,想个几次就会海阔天空)
function Cat() {
this.eat = () => 'apple';
}
const nini = new Cat();
console.log(nini.constructor);//[Function: Cat]
function Dog() {
this.sleep = () => 'sleep';
}
const doggy = new Dog();
console.log(doggy.constructor);//Function: Dog]
两个实例一个nini和一个doggy 找找他们建构子
可以看到nini.constructor和doggy.constructor的原始函式参照是[Function: Cat]
和[Function: Dog]
可以说是 nini.constructor等同於Cat
因此可以使用 nini.constructor来创建新物件
function Cat() {
this.eat = () => 'apple';
}
const nini = new Cat();
const kiki = new nini.constructor();//我直接找Cat function的参照来建立实例
console.log('nini使用建构函式创出', nini);
//nini使用建构函式创出 Cat { eat: [Function (anonymous)] }
console.log('kiki使用nini的建构子创出', kiki);
//kiki使用nini的建构子创出 Cat { eat: [Function (anonymous)] }
console.log(nini.constructor == kiki.constructor);//true
console.log(nini instanceof Cat);//true
nini.constructor
和 kiki.constructor
都是同样的指向Cat
也可以试试看基本型别
let name = 'wendy';
let mystring = name.constructor('abc');
console.log(mystring);//'abc'
name由String()
产生的实例所以他的mystring.__proto__
会是String的prototype
String的prototype内属性:[[prototype]]
会是Object的prtotype
Object的prtotype内属性[[prototype]]
会是null
会了这些,继续讲昨天的疑问
function Cat() {
this.eat = () => 'apple';
}
const nini = new Cat();
Cat.prototype.sleep = 'sleep';
console.log(Object.getPrototypeOf(nini));
//{ sleep: 'sleep' }
//改变Cat的原型
Cat.prototype = {
go: function () {
return 'go';
},
};
const niki = new Cat();
console.log(nini instanceof Cat); //Cat原型是否出现在nini上:false
console.log(nini.constructor); //[Function: Cat]
// 那新实例(niki)呢?
console.log(niki instanceof Cat);///Cat原型是否出现在niki上:true
console.log(niki.constructor); //[Function: Object]
问题:为何niki.constructor 印出是[Function: Object]
因为
//这是Cat修改後的原型(没有constructor属性)
{ go: function () {
return 'go';
}, }
这个object没有constructor属性,通常建构函式的prototype内有constructor属性,因为修改了建构函式的prototype所以constuctor消失了!!!
所以跑的这句niki.constructor,其实niki会往上一层找到Cat的prototype
但自建object 没有constructor,所以会根据原型链再往上找,
找到{ }本身的[[prototype]]
里的constructor
会像是长这样
此时这区是Object地盘(是大写O),他是建构函式的其中一种,因此他的prototype里会有constructor,
Object.prototype.constructor
登愣!!!
所以niki才会印出Object
1.复制别人的方法/属性
把constructor的prototype的某一个methods复制过来,
像是底下把Wendy.prototype.sleep
methods贴到另一个建构函式的methods内
function Wendy() {}
Wendy.prototype.sleep = '今天睡满24hr,超爽的';
Wendy.prototype.eat = '今天吃满24hr';
function Ann() {}
Ann.prototype = { goSleep: Wendy.prototype.sleep }; //wendy 的sleep能力挂在ann身上
const a = new Ann();
console.log(a.goSleep);//今天睡满24hr,超爽的
console.log(a.eat);//undefined
console.log(a instanceof Ann); //true
console.log(a.constructor); //[Function: Object]
这只是复制不是继承
console.log(a instanceof Wendy); //false
那要说说继承了~~
function Go() {}
function Run() {}
Go.prototype.school = 'sleep';
Run.prototype = new Go();
const student = new Run();
console.log(student instanceof Go);//true
console.log(student instanceof Run);//true
console.log(student.school);//sleep
Go的原型换成new Go()物件实例
透过student物件来存取school方法,JS执行环境会先对student物件找寻有没有school方法,没有方法就回去找他的原型:Go物件
先到这里~明天再接再厉
LAST Day 终於到了铁人赛的最後一天,过程中复习了不少的东西,对某些用法有了更加的认识,过程中...
一级函数 (First Class Functions) Everything you can do...
最近有朋友回中国内地工作,刚好问我有什麽VPN推荐一下给他,需要在内地能翻墙,连脸书就可以了,了解他...
HTML的基本架构 首先 我使用的编辑器是VS CODE 因为它的介面还蛮适合新手 而且提供很多套件...
前言 音乐家的艺术不在於直接描绘形象,而在於把心灵置於这些物件能够在心灵里创造的情绪中去。—— 卢梭...