js闭包中修改私有属性和私有方法-题解

目录

前言:

题目原型:

涉及知识点:

解答思路:

解答完整代码:

参考资料:

收获:

推荐学习资料:

致谢:


前言:

在公司搬砖中,被大佬出的题目难倒,自身js基础不扎实,在大佬@深海鱼的耐心指导下,有所收获。希望对你们有所帮助!建议读题后,先试着阅读参考资料自己思考一会儿

题目原型:

let wrap = (function(){
  let pro = {
    say: function() {
      console.log("hello world!")
    }
  }
  let o = Object.create(pro)
  o.a = 1
  o.b = 2
  return {
    get: function(key) {
      return o[key]
    }
  }
})()
​
// 在不修改以上代码的情况下,提问:
// 1.修改o里面的属性
// 2.重写pro的方法

涉及知识点:

  • 原型-原型链(原型链查找)

  • 闭包

  • 立即执行函数

  • 考察-修改闭包中的私有属性以及私有方法

解答思路:

  1. 给所有对象原型添加一个属性,并给这个属性重写其getter方法,返回this

  2. 通过对象的原get方法传入那个新添加的属性,依照原型链查找,可以找到新添加的属性,并返回当前该属性的指向的实例对象

解答完整代码:

let wrap = (function() {
  let pro = {
    say: function() {
      console.log('hello world!')
    }
  }

  let o = Object.create(pro)
  o.a = 1
  o.b = 2

  return {
    get: function(key) {
      console.log('key')
      return o[key]
    }
  }
})()

// 提问:
// 在不改变上方代码的情况下
// 1.修改o里面的属性
// 2.重写pro对象的say方法

// 给所有对象原型添加一个叫getThis的属性,并给这个属性重载一个getter访问器属性
Object.defineProperty(Object.prototype, 'getThis', {
  get: function() {
    console.log('进入这里')
    return this
  }
})

// Object作为顶级对象的构造函数,它实例的原型本身就不再有原型了,因此它原型为null
console.log(typeof Object)

// 拿到o对象
let testProto = wrap.get('getThis')
console.log(testProto)

// 拿到o对象的原型 - pro
let oPrototype = Object.getPrototypeOf(testProto)
// let oPrototype = testProto.__proto__  // 效果一致
console.log(oPrototype)
console.log(oPrototype.say())

// 修改o对象中的属性值
testProto.a = 3
console.log(testProto)

// 重写pro对象中的say方法
oPrototype.say = function() {
  console.log('被修改了')
}
console.log(oPrototype.say())

参考资料:

收获:

  • this 的值是在代码运行时计算出来的,它取决于代码上下文。 在 JavaScript 中,this 是“自由”的,它的值是在调用时计算出来的,它的值并不取决于方法声明的位置,而是取决于在“点符号前”的是什么对象。

  • this 的值是在程序运行时得到的。

    • 一个函数在声明时,可能就使用了 this,但是这个 this 只有在函数被调用时才会有值。

    • 可以在对象之间复制函数。

    • 以“方法”的语法调用函数时:object.method(),调用过程中的 this 值是 object

    请注意箭头函数有些特别:它们没有 this。在箭头函数内部访问到的 this 都是从外部获取的。

  • 使用__proto__是有争议的,也不鼓励使用它。因为它从来没有被包括在EcmaScript语言规范中,但是现代浏览器都实现了它。__proto__属性已在ECMAScript 6语言规范中标准化,用于确保Web浏览器的兼容性,因此它未来将被支持。但是,它已被不推荐使用,现在更推荐使用Object.getPrototypeOf/Reflect.getPrototypeOfObject.setPrototypeOf/Reflect.setPrototypeOf(尽管如此,设置对象的原型是一个缓慢的操作,如果性能要求很高,应该避免设置对象的原型)。

推荐学习资料:

致谢:

@深海鱼,感谢公司大佬耐心指导,帮助我更好的学习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值