如何在自定义 Object.prototype.xxx 函数中获取对象本身? [英] How to get object itself in custom Object.prototype.xxx function?

查看:20
本文介绍了如何在自定义 Object.prototype.xxx 函数中获取对象本身?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Object.prototype.getB = function() {

  // how to get the current value a
  return a.b;

};
const a = {b: 'c'};
a.getB();

如您所见,我想为所有 Object 值制作一个函数.我需要在这个函数中获取对象值然后做一些事情.

As you can see, I want to make a function to all Object value. And I need to get the object value in this function then do something.

推荐答案

Monkey Patching

你想做的是猴子补丁 — 你改变一个内置原型.有很多错误的方法可以做到,但我将演示一种目前最正确的方法.

Monkey Patching

What you want to do is called monkey patching — you mutate a built-in prototype. There are many wrong ways to do it, but I’ll demonstrate a way that is currently the most correct way.

在您的情况下,函数体应返回 this.b.您可以使用 this 关键字获取对象本身.

In your case, the function body should return this.b. You can get the object itself with the this keyword.

如果你真的想打猴子补丁,事先检查函数是否存在以确保向前兼容并使属性可写、可配置和不可枚举(最后一个是默认值)使用 defineProperty 时).提取 方法 使 getB 一个不可构造的函数.所有这些确保 getB 的行为与现有的内置方法(或宿主环境提供的方法)非常相似.

If you really want to monkey-patch, check for the function’s existence beforehand to ensure forward-compatibility and make the property writable, configurable, and non-enumerable (the last of which is the default when using defineProperty). Extracting a method makes getB a non-constructible function. All this ensures that getB behaves very much like existing built-in methods (or methods provided by the host environment).

if(!Object.hasOwn(Object.prototype, "getB")){
  Object.defineProperty(Object.prototype, "getB", {
    writable: true,
    configurable: true,
    value: {
      getB(){
        return this.b;
      }
    }.getB
  });
}

Object.hasOwn 是一种相当新的方法,但在旧环境中,它可以简单地替换为 Object.prototype.hasOwnProperty.call 或其变体.如果您不能支持方法,请改用它:

Object.hasOwn is quite a new method, but in older environments it can simply be replaced by Object.prototype.hasOwnProperty.call or a variant thereof. If you can’t support methods, use this instead:

if(!Object.prototype.hasOwnProperty("getB")){
  Object.defineProperty(Object.prototype, "getB", {
    writable: true,
    configurable: true,
    value: function getB(){
      return this.b;
    }
  });
}

请记住,箭头函数 不能用于此目的,因为它们没有自己的 this 绑定.

Keep in mind that arrow functions cannot be used for this purpose since they don’t have their own this binding.

另一种方法是使用吸气剂.考虑一下:

An alternative is to use a getter. Consider this:

const arr = [
    "a",
    "b",
    "c",
  ];

console.log(arr.indexOfB); // 1

Array 原型上的 indexOfB getter 是什么样的?我们不能用上面的方法用get代替value,否则我们会得到:

How would an indexOfB getter on the Array prototype look like? We can’t use the above approach and replace value by get, or else we’ll get:

TypeError:当指定了 getter 或 setter 时,属性描述符不得指定值或可写

TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified

属性writable 需要从描述符中完全删除.现在 value 可以替换为 get:

The property writable needs to be removed entirely from the descriptor. Now value can be replaced by get:

if(!Array.prototype.hasOwnProperty("indexOfB")){
  Object.defineProperty(Array.prototype, "indexOfB", {
    configurable: true,
    get: {
      indexOfB(){
        return this.indexOf("b");
      }
    }.indexOfB
  });
}

还可以通过向描述符添加 set 属性来指定 setter:

A setter can also be specified by adding a set property to the descriptor:

if(!Array.prototype.hasOwnProperty("indexOfB")){
  Object.defineProperty(Array.prototype, "indexOfB", {
    configurable: true,
    get: {
      indexOfB(){
        return this.indexOf("b");
      }
    }.indexOfB,
    set: {
      indexOfB(newValue){
        // `newValue` is the assigned value.
        // Use `this` for the current Array instance.
        // No `return` necessary.
      }
    }.indexOfB
  });
}

这篇关于如何在自定义 Object.prototype.xxx 函数中获取对象本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆