How to copy functions in javascript

For http://stackoverflow.com/questions/17499676/javascript-function-copies

by spoike

HTML

<ul id="testResults">
</ul>

CSS

body: { margin: 0; padding: 0; }
ul {
    margin: 0; padding: 0;
    list-style: none;    
    font-family: Arial, sans-serif;
}
ul li {
    margin: 0; padding: 10px 15px;
}
.pass {
    background-color: darkgreen;
    color: white;
    font-weight: bold;
}
.fail {
    background-color: darkred;
    color: white;
    font-weight: bold;
}

JavaScript

// Assertion function that adds to the test results list
function assert(b, str) {
  var results = document.getElementById('testResults');
  var result = document.createElement('li');
  result.setAttribute('class', (b ? 'pass' : 'fail'));
  result.innerHTML = str;
  results.appendChild(result);
}
function append(str) {
  var results = document.getElementById('testResults'); var result = document.createElement('li'); result.innerHTML = str; results.appendChild(result);
}

append('test1 - OP\'s code');

// test 1
// --------------------------------
var make = function (x) {
    var thing = {
        x: x 
    };

    thing.do = function () {
        this.x++;
    };

    return thing;
};

var x1 = make(1);
var x2 = make(2);
// note the inequality
assert(x1.do !== x2.do, 'x1.do and x2.do should not have the same function');

append('test2 - using the same function');

// test 2 - using the same function
// --------------------------------
var doFunc = function() {
    this.x++;
}
make = function (x) {
    var thing = {
        x: x 
    };

    thing.do = doFunc;

    return thing;
};

x1 = make(1);
x2 = make(2);
assert(x1.do === x2.do, 'x1.do and x2.do should have the same function');
x1.do();
assert(x1.x === x2.x, 'this.x++ should work');

append('test3 - use a prototype');

// test 3 - use a prototype
// ------------------------
var thingProto = {
    x: 0,
    do: function() { this.x++; }
};
make = function (x) {
    var o = Object.create(thingProto);
    o.x = x;
    return o;
};
x1 = make(1);
x2 = make(2);
assert(x1.do === x2.do, 'x1.do and x2.do should have the same function');
x1.do();
assert(x1.x === x2.x, 'this.x++ should work');