前端 每日一道面试题(6)2021-09-09

本文详细探讨了JavaScript中的作用域链和原型链,通过实例分析了`Foo`构造函数及其原型方法的比较。讲解了`this`的指向、函数实例的属性查找过程以及`__proto__`与`prototype`的关系。最后,通过原型链图解帮助读者深入理解这一核心概念。
摘要由CSDN通过智能技术生成

hello! 每日一道面试题 大厂offer等着你
今天我们的面试题主要考察的是作用域链
看题 然后说写出打印结果

function Foo() {
 this.m = 10
 this.n = 24
 this.getM = function () {
    console.log(this.m)
  }
}
Foo.prototype.getM = function () {
  console.log(this.m)
}

Foo.prototype.getN = function () {
  console.log(this.n)
}

let foo1 = new Foo
let foo2 = new Foo
console.log(foo1.getM === foo2.getM)  
console.log(foo1.getN === foo2.getN)
console.log(foo1.__proto__.getN === Foo.prototype.getN)  
console.log(foo1.__proto__.getM === foo2.getM) 
console.log(foo1.getM === Foo.prototype.getM) 
console.log(foo1.constructor) 
console.log(Foo.prototype.__proto__.constructor) 
foo1.getM()  
foo1.__proto__.getM() 
foo2.getN()  
Foo.prototype.getN() 

解析如下


function Foo() {
 this.m = 10
 this.n = 24
 this.getM = function () {
    console.log(this.m)
  }
}
Foo.prototype.getM = function () {
  console.log(this.m)
}

Foo.prototype.getN = function () {
  console.log(this.n)
}

let foo1 = new Foo
let foo2 = new Foo
console.log(foo1.getM === foo2.getM)    //false
console.log(foo1.getN === foo2.getN)    //true
console.log(foo1.__proto__.getN === Foo.prototype.getN)   //true
console.log(foo1.__proto__.getM === foo2.getM)        //false
console.log(foo1.getM === Foo.prototype.getM)        //false
console.log(foo1.constructor)               
// ƒ Foo() {
//  this.m = 10
//  this.n = 24
//  this.getM = function () {
//    console.log(this.m)
//  }
//}
console.log(Foo.prototype.__proto__.constructor) //ƒ Object() { [native code] }

foo1.getM()  //10
foo1.__proto__.getM()    //undefined 
foo2.getN()       //20
Foo.prototype.getN()   //undefined

解析

  1. 首先 第一行 false,因为我们每个new出来的对象 都会新建一个对象,首先从自己的身上找,找到了,因为都是new出来的,所以地址不同 所以不相等 返回false\
  2. 跟上面一样 先从自己身上找,没找到;顺着构造函数的原型prototype找 ,找到了,因为他们的原型指向同一个 所以 返回true\
  3. foo1.proto指向构造函数的prototype 所以 true
    4.foo1.
    proto_.getM指向的是构造函数的getM; foo2.getM指向的是自己的私有属性 所以false\
  4. foo1.getM指向的是身的getM 而Foo.prototype.getM 指向的是构造函数的getM 所以 返回 false\
  5. foo1.constructor 实例对象的constructor 指向构造函数 所以打印的及时构造函数本身\
  6. Foo.prototype.proto.constructor, Foo.prototype 指向构造函数的原型对象 Foo.prototype.__proto__指向构造函数的原型对象 的 一个匿名函数的 实例对象 Foo.prototype.proto.constructor 指想匿名函数本身\
  7. foo1.getM() 打印的是自身私有属性的m里面可以找到 所以打印的是10\
  8. foo1._proto .getM() 指向的是 Foo实例对象的 也就是Foo.prototype.getM 而这里面没有m这个属性 顺着原型链prototype往上找也没有 所以打印的是undefined
    10.Foo.prototype.getN() 里面也没有n这个属性 顺着原型链prototype往上找也没有 所以是undefined
    复制代码

为了方便大家理解 这里做了一个原型链的流程图
在这里插入图片描述

好了,今天的分享到这了
喜欢的记得 点赞! 收藏~ +关注哟!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值