是否可以修改定义的getter函数?

时间:2017-08-28 05:46:27

标签: javascript wechat

在微信迷你应用程序平台(基于微信应用程序的javascript +本机混合)上使用性能审查工具,我试图将代码注入其原型,例如wx.request函数。

这是您使用wx.request函数的方式:

wx.request({
  url: 'test.php',
  data: {
     x: '' ,
     y: ''
  },
  header: {
      'content-type': 'application/json'
  },
  success: function(res) {
    console.log(res.data)
  }
})

因此,为了知道在没有手动编写添加所有锚点的情况下请求已经花了多长时间,我试图通过以下方式注入代码:

var owxrequest = wx.request
wx.request = function() {
  console.log('test', Date.now())
  return owxrequest.apply(owxrequest, arguments)
}

此操作失败,我收到Cannot set property "prop" of #<Object> which has only a getter错误。

所以我意识到对象必须被定义为类似于:

wx = {
  request: get function(){
    ...
  }
  ...
}

所以我试过了:

var owxrequest = wx.request
Object.defineProperty(wx, 'request', {
  get: function() {
    console.log('test', Date.now())
    return owxrequest.apply(owxrequest, arguments)
  }
})

失败并显示错误(request: fail parameter error: parameter.url should be String instead of Undefined)。然后我试了一下:

var owxrequest = wx.request
Object.defineProperty(wx, 'request', {
  set: function() {
    console.log('test', Date.now())
    return owxrequest.apply(owxrequest, arguments)
  }
})

这不会引发错误,但在调用wx.request()时也无效...

2 个答案:

答案 0 :(得分:1)

您可以通过重新定义getter来实现此目的。重点是:重新定义的getter应返回一个函数对象,因为wx.request是一个函数:

Object.defineProperty(wx, 'request', {
  get: function() {
    return function() {
      //...
    };
  }
});

为什么我收到错误:request: fail parameter error: parameter.url should be String instead of Undefined

您正在尝试访问getter本身的argumentsarguments中的get: function(){...}函数。此arguments是一个空对象,可以通过console.log()语句进行验证。由于它是空的,arguments.url未定义,这就是wx抱怨参数的原因。

以下是一个工作示例:

let wx = {
  get request(){
    return function() {
      console.log(10);
      return 88;
    };
  }
};

let oldF = wx.request;

Object.defineProperty(wx, 'request', {
  get: function() {
    return function() {
      console.log(new Date());
      return oldF.apply(wx, arguments);
    };
  }
});

console.log(wx.request());

上面的代码会打印出来:

2017-08-28T06:14:15.583Z // timestamp
10
88

答案 1 :(得分:0)

您可以隐藏request功能。 简单的例子:

遮蔽吸气剂:

// original getter latest
let base = {
  num: 1,
  get latest() {
    return this.num;
  }
}
console.log(base.latest);

// shadowing getter latest
Object.defineProperty(base, 'latest', {
  get: function() {
    return this.num + 1;
  }
});

console.log(base.latest);

简单遮蔽对象属性

// your original object
let base = {
    request(){
        console.log('request original');
    }
};

base.request()


base.request = () => {
    console.log('request new implementation');
};
 
// now shadow the original request implementation
base.request()