话不多说,下面这段代码的结果是啥
const obj = {name:'obj'};
console.log(
obj.__proto__.constructor
===
obj.__proto__.constructor.__proto__.__proto__.constructor
)
握草,这啥?这能有结果?
还是先上一段熟悉的,下面这段代码的打印结果想必帅哥镁铝都应该知道吧,
Object.prototype.Flag = '一个标记'
function People(name) { //构造函数
this.name = name
}
People.prototype.sleep = '有睡觉的本领' // 为 People 的原型上添加属性
const tom = new People('tom')
console.log(tom.__proto__ === People.prototype)
console.log(tom.Flag)
很明显,打印的结果为
因为 tom.proto 和 People.prototype 都指向同一处,就是 People 的原型(People.prototype),而且 People 的原型 也含有私有属性 proto 指向 Object.prototype 所以 man 的实例也能打印出 Flag 标记,来看看它的原型链(下图):
我们要打印 tom.Flag tom 没有,他会沿着原型链向上找到 People.prototype,没有则继续向上找,有则停止(如果到 null 还没找到则会返回 undefined) ,这就是原型链查找的过程,好,根据上述示例,我来引入一个问题一,如果在 tom 这更改这个标记,结果是啥。
问题1:下面的打印结果是:
Object.prototype.Flag = '一个标记'
function People(name) { //构造函数
this.name = name
}
People.prototype.sleep = '有睡觉的本领' // 为 People 的原型上添加属性
const tom = new People('tom')
console.log(tom.Flag) // '一个标记'
tom.Flag = 'tom的标记'
console.log(tom.Flag)
console.log(Object.prototype.Flag)
哎哎,偏题了,拉回来,不过也算复习下,我们继续来看开头的这段代码打印的结果是啥
const obj = {name:'obj'};
console.log(
obj.__proto__.constructor
===
obj.__proto__.constructor.__proto__.__proto__.constructor
)
这次我们来换张图,
你可以把我们刚才讲的看做我圈出来的这部分
有助于你理解这张图,现在要看其他部分,根据题目的第一部分,他用隐式创建了一个对象 const obj = {name:'obj'}; 可以将 obj 看做 上图的 o1 在根据他的第一个要打印的第一个值 obj.__proto__.constructor 在图上可以找到,就是 Object.prototype 要的打印的第二个值obj.__proto__.constructor.__proto__.__proto__.constructor 你仔细找找,是不是经过 Function.prototype 又绕回去了,又是 Object.prototype ,那他量不就相等了么。好吧大无语事件,看了这么长时间看了个寂寞。
那他两既然相等, 那就是说.....................
那可以在控制台一直这样点下去,每经过一个这个 __proto__.__proto__.constructor 他两就相等,就类似于这样
他两形成一个环,只要你一直点他就一直有。
拉回来,既然 obj.__proto__.constructor.__proto__.__proto__.constructo 即然他形成了环,但为什么会在他们三个间形成环(对象的构造函数,对象的原型,函数的原型),为了更好的理解,我把他强加到我们上文的第一个例子了,虚线是新加的。
先来看下虚线框右边的 function 构造函数这块
好,接下来震惊三联
震惊一:函数的原型 proto 指向对象的原型。
震惊二:对象的构造函数 proto 指向函数的原型
震惊三:函数的原型链最终也会到达--> Object.prototype --> null,
震惊三足够能说明为啥好多人都认为 js 是万物基于对象,那你咋不说对象还是由函数构造的(狗头保命) 哎我也解释不清楚,反正 js 就是这么神奇,可以理解我函数和对象相辅相成,没有谁基于谁。
还不信?
console.log(Object.constructor instanceof Function); // true
console.log(Function.constructor instanceof Function); //true
这下应该没问题了。
好,那个问题一的答案是
Object.prototype.Flag = '一个标记'
function People(name) { //构造函数
this.name = name
}
People.prototype.sleep = '有睡觉的本领' // 为 People 的原型上添加属性
const tom = new People('tom')
console.log(tom.Flag) // '一个标记'
tom.Flag = 'tom的标记'
/*
并不会改变 Object.prototype 上的 Flag,因为属性访问到 tom.Flag 为 undefined 后并不会向上找,
因为有赋值操作符,覆盖 undefined ,最终返回具有该属性则停止查找。
*/
console.log(tom.Flag) //'tom的标记'
console.log(Object.prototype.Flag) //'一个标记'
这块还有很多知识,在完善吧,如果有错请大佬回复。