javascript - 拦截javascript中对象的方法

标签 javascript

我知道如何拦截 JavaScript 中的原生函数。例如,我使用下面的代码来拦截document.createElement:

var origParseFloat = document.createElement;
document.createElement = function(str) {
     alert("Called");
     return origParseFloat(str);
}

我的问题是如何拦截对象的方法。 我的意思是,如果我想拦截 toDataURL(),这是 CanvasElement 的一种方法。上面的代码在这种情况下不起作用。 所以现在的主要问题是如何在如下情况下拦截 toDataURL():

canvas = document.createElement('canvas');
var tdu = canvas.toDataURL();

最佳答案

您需要在它出现的 prototype 上修补该方法,在您的情况下为 HTMLCanvasElement.prototype.toDataURL .

var origToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() {
  var r = origToDataURL.apply(this, arguments);
  console.log('toDataURL:', r);
  return r;
};


var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 50, 50);
canvas.toDataURL();
<canvas id="canvas" width="100" height="100"></canvas>

或者,如果您知道 canvas 元素是使用 document.createElement 创建的,我想您可以在该实例上定义一个新方法,但这种方法不太可靠,因为使用 HTML 创建的元素会被遗漏,并且对象结构在技术上是不同的。

您也可以对 getter 函数执行类似的操作。

// Function to find the prototype chain object that has a property.
function findPrototypeProperty(obj, prop) {
    while (!obj.hasOwnProperty(prop)) {
        obj = Object.getPrototypeOf(obj);
    }
    return obj;
}

var property = 'sampleRate';
var proto = findPrototypeProperty(AudioContext.prototype, property);

var desc = Object.getOwnPropertyDescriptor(proto, property);
var getter = desc.get;
desc.get = function() {
    var r = getter.apply(this, arguments);
    console.log(property, r);
    return r;
};
Object.defineProperty(proto, property, desc);


var audioCtx = new AudioContext();
void(audioCtx.sampleRate);

关于javascript - 拦截javascript中对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49353301/

相关文章:

javascript - 为什么有些 slider 会发出红光?

javascript - JS销毁触发函数

Javascript 命名空间。它会提高 JS/浏览器性能吗?

javascript - AngularJS ng-repeat 在填充表时创建三个空行并且 ng-repeat 不重复

javascript - 最近更新的 `@types/node` 版本正在创建错误。以前的版本工作正常

javascript - 如何使用装饰器向类添加函数

javascript - 将两个数组合并为一个具有相同数量对象的数组

javascript - 将业务对象序列化为 JSON

javascript - 我想使用 jQuery 在 html 中使用 data-* 属性将占位符设置为文本框?

javascript - innerHTML 不会在每个 keydown 事件中改变