在javascript中拦截对象的方法

时间:2018-03-18 22:06:30

标签: 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();

1 个答案:

答案 0 :(得分:5)

您需要在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>
&#13;
&#13;
&#13;

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

你也可以为getter函数做类似的事情。

&#13;
&#13;
// 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);
&#13;
&#13;
&#13;