Home  >  Article  >  Web Front-end  >  Detailed examples of the difference between the function of JavaScript decorator pattern and proxy pattern

Detailed examples of the difference between the function of JavaScript decorator pattern and proxy pattern

伊谢尔伦
伊谢尔伦Original
2017-07-24 14:36:011971browse

The decorated pattern can dynamically add some additional responsibilities to an object without affecting other objects derived from this class.

The decorated pattern embeds one object into another object, which is actually equivalent to this object being wrapped by another object, forming a packaging chain.

Add some additional functions to the function without changing the original function

1. Save the original reference


window.onload = function() {
  console.log(1);
};

var _onload = window.onload || function() {};

window.onload = function() {
  _onload();
  console.log(2);
}

Problem:
(1) Intermediate variables must be maintained
(2) This may be hijacked
In the example of window.onload, there is no such trouble because when calling the ordinary function _onload, this also points to window, just like when calling window.onload.

2. this is hijacked:


var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById(id);
}

return _getElementById(id); // 报错“Uncaught TypeError: Illegal invocation”

Because _getElementById is a global function, when calling the global function, this points to the window, and in document.getElementById this is expected to point to the document.

3. Solve this being hijacked:


##

var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById.call(document, id);
}

Decorate the function with AOP


/* 让新添加的函数在原函数之前执行(前置装饰)*/
Function.prototype.before = function(beforefn) {
  var _self = this;
  return function() {
    beforefn.apply(this, arguments);  // 新函数接收的参数会被原封不动的传入原函数
    return _self.apply(this, arguments);
  };
};


/* 让新添加的函数在原函数之后执行(后置装饰)*/
Function.prototype.after = function(afterfn) {
  var _self = this;
  return function() {
    var ret = _self.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  };
};


document.getElementById = document.getElementById.before(function() {
  console.log(1);
});

Avoid polluting prototypes


var before = function(fn, beforefn) {
  return function() {
    beforefn.apply(this, arguments);
    return fn.apply(this, arguments);
  };
};

var after = function(fn, afterfn) {
  return function() {
    var ret = fn.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  };
};

document.getElementById = before(document.getElementById, function(){
  console.log(1);
});

Decorator pattern and proxy pattern

Same points: Both patterns describe how to provide a certain level of functionality to objects Indirect references, their implementation parts retain a reference to another object and send a request to that object.

Difference:
(1) Proxy mode: When direct local access is inconvenient or does not meet the needs, provide a substitute for this ontology. Define key functionality locally, and the agent provides or denies access to it, or does some extra things before accessing the ontology. (It still does the same thing as the ontology)
(2) Decorator mode: Dynamically add behaviors to the object. (You cannot determine all the functions of the object at the beginning, and actually add new responsibilities and behaviors to the object)

The above is the detailed content of Detailed examples of the difference between the function of JavaScript decorator pattern and proxy pattern. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn