├── .npmrc ├── index.js ├── .github ├── SECURITY.md ├── workflows │ ├── node-pretest.yml │ ├── require-allow-edits.yml │ ├── node-aught.yml │ ├── node-tens.yml │ └── rebase.yml └── FUNDING.yml ├── test ├── .eslintrc └── index.js ├── .nycrc ├── .eslintrc ├── LICENSE ├── README.md ├── implementation.js ├── package.json ├── .gitignore └── CHANGELOG.md /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | allow-same-version=true 3 | message=v%s 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var implementation = require('./implementation'); 4 | 5 | module.exports = Function.prototype.bind || implementation; 6 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. 4 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "array-bracket-newline": 0, 4 | "array-element-newline": 0, 5 | "max-statements-per-line": [2, { "max": 2 }], 6 | "no-invalid-this": 0, 7 | "no-magic-numbers": 0, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/node-pretest.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: pretest/posttest' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/pretest.yml@main 11 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "all": true, 3 | "check-coverage": false, 4 | "reporter": ["text-summary", "text", "html", "json"], 5 | "lines": 86, 6 | "statements": 85.93, 7 | "functions": 82.43, 8 | "branches": 76.06, 9 | "exclude": [ 10 | "coverage", 11 | "test" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | 4 | "extends": "@ljharb", 5 | 6 | "rules": { 7 | "func-name-matching": 0, 8 | "indent": [2, 4], 9 | "no-new-func": [1], 10 | }, 11 | 12 | "overrides": [ 13 | { 14 | "files": "test/**", 15 | "rules": { 16 | "max-lines-per-function": 0, 17 | "strict": [0] 18 | }, 19 | }, 20 | ], 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/require-allow-edits.yml: -------------------------------------------------------------------------------- 1 | name: Require “Allow Edits” 2 | 3 | on: [pull_request_target] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | _: 10 | permissions: 11 | pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR 12 | name: "Require “Allow Edits”" 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: ljharb/require-allow-edits@main 18 | -------------------------------------------------------------------------------- /.github/workflows/node-aught.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js < 10' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '< 10' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node < 10' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: 'echo tests completed' 22 | -------------------------------------------------------------------------------- /.github/workflows/node-tens.yml: -------------------------------------------------------------------------------- 1 | name: 'Tests: node.js >= 10' 2 | 3 | on: [pull_request, push] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | tests: 10 | uses: ljharb/actions/.github/workflows/node.yml@main 11 | with: 12 | range: '>= 10' 13 | type: minors 14 | command: npm run tests-only 15 | 16 | node: 17 | name: 'node >= 10' 18 | needs: [tests] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - run: 'echo tests completed' 22 | -------------------------------------------------------------------------------- /.github/workflows/rebase.yml: -------------------------------------------------------------------------------- 1 | name: Automatic Rebase 2 | 3 | on: [pull_request_target] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | _: 10 | permissions: 11 | contents: write # for ljharb/rebase to push code to rebase 12 | pull-requests: read # for ljharb/rebase to get info about PR 13 | name: "Automatic Rebase" 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - uses: ljharb/rebase@master 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ljharb] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: npm/function-bind 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Raynos. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # function-bind [![Version Badge][npm-version-svg]][package-url] 2 | 3 | [![github actions][actions-image]][actions-url] 4 | 5 | [![dependency status][deps-svg]][deps-url] 6 | [![dev dependency status][dev-deps-svg]][dev-deps-url] 7 | [![License][license-image]][license-url] 8 | [![Downloads][downloads-image]][downloads-url] 9 | 10 | [![npm badge][npm-badge-png]][package-url] 11 | 12 | Implementation of function.prototype.bind 13 | 14 | Old versions of phantomjs, Internet Explorer < 9, and node < 0.6 don't support `Function.prototype.bind`. 15 | 16 | ## Example 17 | 18 | ```js 19 | Function.prototype.bind = require("function-bind") 20 | ``` 21 | 22 | ## Installation 23 | 24 | `npm install function-bind` 25 | 26 | ## Contributors 27 | 28 | - Raynos 29 | 30 | ## MIT Licenced 31 | 32 | [package-url]: https://npmjs.org/package/function-bind 33 | [npm-version-svg]: https://versionbadg.es/Raynos/function-bind.svg 34 | [deps-svg]: https://david-dm.org/Raynos/function-bind.svg 35 | [deps-url]: https://david-dm.org/Raynos/function-bind 36 | [dev-deps-svg]: https://david-dm.org/Raynos/function-bind/dev-status.svg 37 | [dev-deps-url]: https://david-dm.org/Raynos/function-bind#info=devDependencies 38 | [npm-badge-png]: https://nodei.co/npm/function-bind.png?downloads=true&stars=true 39 | [license-image]: https://img.shields.io/npm/l/function-bind.svg 40 | [license-url]: LICENSE 41 | [downloads-image]: https://img.shields.io/npm/dm/function-bind.svg 42 | [downloads-url]: https://npm-stat.com/charts.html?package=function-bind 43 | [codecov-image]: https://codecov.io/gh/Raynos/function-bind/branch/main/graphs/badge.svg 44 | [codecov-url]: https://app.codecov.io/gh/Raynos/function-bind/ 45 | [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/Raynos/function-bind 46 | [actions-url]: https://github.com/Raynos/function-bind/actions 47 | -------------------------------------------------------------------------------- /implementation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint no-invalid-this: 1 */ 4 | 5 | var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; 6 | var toStr = Object.prototype.toString; 7 | var max = Math.max; 8 | var funcType = '[object Function]'; 9 | 10 | var concatty = function concatty(a, b) { 11 | var arr = []; 12 | 13 | for (var i = 0; i < a.length; i += 1) { 14 | arr[i] = a[i]; 15 | } 16 | for (var j = 0; j < b.length; j += 1) { 17 | arr[j + a.length] = b[j]; 18 | } 19 | 20 | return arr; 21 | }; 22 | 23 | var slicy = function slicy(arrLike, offset) { 24 | var arr = []; 25 | for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) { 26 | arr[j] = arrLike[i]; 27 | } 28 | return arr; 29 | }; 30 | 31 | var joiny = function (arr, joiner) { 32 | var str = ''; 33 | for (var i = 0; i < arr.length; i += 1) { 34 | str += arr[i]; 35 | if (i + 1 < arr.length) { 36 | str += joiner; 37 | } 38 | } 39 | return str; 40 | }; 41 | 42 | module.exports = function bind(that) { 43 | var target = this; 44 | if (typeof target !== 'function' || toStr.apply(target) !== funcType) { 45 | throw new TypeError(ERROR_MESSAGE + target); 46 | } 47 | var args = slicy(arguments, 1); 48 | 49 | var bound; 50 | var binder = function () { 51 | if (this instanceof bound) { 52 | var result = target.apply( 53 | this, 54 | concatty(args, arguments) 55 | ); 56 | if (Object(result) === result) { 57 | return result; 58 | } 59 | return this; 60 | } 61 | return target.apply( 62 | that, 63 | concatty(args, arguments) 64 | ); 65 | 66 | }; 67 | 68 | var boundLength = max(0, target.length - args.length); 69 | var boundArgs = []; 70 | for (var i = 0; i < boundLength; i++) { 71 | boundArgs[i] = '$' + i; 72 | } 73 | 74 | bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder); 75 | 76 | if (target.prototype) { 77 | var Empty = function Empty() {}; 78 | Empty.prototype = target.prototype; 79 | bound.prototype = new Empty(); 80 | Empty.prototype = null; 81 | } 82 | 83 | return bound; 84 | }; 85 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "function-bind", 3 | "version": "1.1.2", 4 | "description": "Implementation of Function.prototype.bind", 5 | "keywords": [ 6 | "function", 7 | "bind", 8 | "shim", 9 | "es5" 10 | ], 11 | "author": "Raynos ", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/Raynos/function-bind.git" 15 | }, 16 | "funding": { 17 | "url": "https://github.com/sponsors/ljharb" 18 | }, 19 | "main": "index", 20 | "homepage": "https://github.com/Raynos/function-bind", 21 | "contributors": [ 22 | { 23 | "name": "Raynos" 24 | }, 25 | { 26 | "name": "Jordan Harband", 27 | "url": "https://github.com/ljharb" 28 | } 29 | ], 30 | "bugs": { 31 | "url": "https://github.com/Raynos/function-bind/issues", 32 | "email": "raynos2@gmail.com" 33 | }, 34 | "devDependencies": { 35 | "@ljharb/eslint-config": "^21.1.0", 36 | "aud": "^2.0.3", 37 | "auto-changelog": "^2.4.0", 38 | "eslint": "=8.8.0", 39 | "in-publish": "^2.0.1", 40 | "npmignore": "^0.3.0", 41 | "nyc": "^10.3.2", 42 | "safe-publish-latest": "^2.0.0", 43 | "tape": "^5.7.1" 44 | }, 45 | "license": "MIT", 46 | "scripts": { 47 | "prepublishOnly": "safe-publish-latest", 48 | "prepublish": "not-in-publish || npm run prepublishOnly", 49 | "prepack": "npmignore --auto --commentLines=autogenerated", 50 | "pretest": "npm run lint", 51 | "test": "npm run tests-only", 52 | "posttest": "aud --production", 53 | "tests-only": "nyc tape 'test/**/*.js'", 54 | "lint": "eslint --ext=js,mjs .", 55 | "version": "auto-changelog && git add CHANGELOG.md", 56 | "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" 57 | }, 58 | "testling": { 59 | "files": "test/index.js", 60 | "browsers": [ 61 | "ie/8..latest", 62 | "firefox/16..latest", 63 | "firefox/nightly", 64 | "chrome/22..latest", 65 | "chrome/canary", 66 | "opera/12..latest", 67 | "opera/next", 68 | "safari/5.1..latest", 69 | "ipad/6.0..latest", 70 | "iphone/6.0..latest", 71 | "android-browser/4.2..latest" 72 | ] 73 | }, 74 | "auto-changelog": { 75 | "output": "CHANGELOG.md", 76 | "template": "keepachangelog", 77 | "unreleased": false, 78 | "commitLimit": false, 79 | "backfillLimit": false, 80 | "hideCredit": true 81 | }, 82 | "publishConfig": { 83 | "ignore": [ 84 | ".github/workflows" 85 | ] 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | 132 | # Only apps should have lockfile 133 | npm-shrinkwrap.json 134 | package-lock.json 135 | yarn.lock 136 | 137 | .npmignore 138 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | // jscs:disable requireUseStrict 2 | 3 | var test = require('tape'); 4 | 5 | var functionBind = require('../implementation'); 6 | var getCurrentContext = function () { return this; }; 7 | 8 | test('functionBind is a function', function (t) { 9 | t.equal(typeof functionBind, 'function'); 10 | t.end(); 11 | }); 12 | 13 | test('non-functions', function (t) { 14 | var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g]; 15 | t.plan(nonFunctions.length); 16 | for (var i = 0; i < nonFunctions.length; ++i) { 17 | try { functionBind.call(nonFunctions[i]); } catch (ex) { 18 | t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i])); 19 | } 20 | } 21 | t.end(); 22 | }); 23 | 24 | test('without a context', function (t) { 25 | t.test('binds properly', function (st) { 26 | var args, context; 27 | var namespace = { 28 | func: functionBind.call(function () { 29 | args = Array.prototype.slice.call(arguments); 30 | context = this; 31 | }) 32 | }; 33 | namespace.func(1, 2, 3); 34 | st.deepEqual(args, [1, 2, 3]); 35 | st.equal(context, getCurrentContext.call()); 36 | st.end(); 37 | }); 38 | 39 | t.test('binds properly, and still supplies bound arguments', function (st) { 40 | var args, context; 41 | var namespace = { 42 | func: functionBind.call(function () { 43 | args = Array.prototype.slice.call(arguments); 44 | context = this; 45 | }, undefined, 1, 2, 3) 46 | }; 47 | namespace.func(4, 5, 6); 48 | st.deepEqual(args, [1, 2, 3, 4, 5, 6]); 49 | st.equal(context, getCurrentContext.call()); 50 | st.end(); 51 | }); 52 | 53 | t.test('returns properly', function (st) { 54 | var args; 55 | var namespace = { 56 | func: functionBind.call(function () { 57 | args = Array.prototype.slice.call(arguments); 58 | return this; 59 | }, null) 60 | }; 61 | var context = namespace.func(1, 2, 3); 62 | st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); 63 | st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); 64 | st.end(); 65 | }); 66 | 67 | t.test('returns properly with bound arguments', function (st) { 68 | var args; 69 | var namespace = { 70 | func: functionBind.call(function () { 71 | args = Array.prototype.slice.call(arguments); 72 | return this; 73 | }, null, 1, 2, 3) 74 | }; 75 | var context = namespace.func(4, 5, 6); 76 | st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); 77 | st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); 78 | st.end(); 79 | }); 80 | 81 | t.test('called as a constructor', function (st) { 82 | var thunkify = function (value) { 83 | return function () { return value; }; 84 | }; 85 | st.test('returns object value', function (sst) { 86 | var expectedReturnValue = [1, 2, 3]; 87 | var Constructor = functionBind.call(thunkify(expectedReturnValue), null); 88 | var result = new Constructor(); 89 | sst.equal(result, expectedReturnValue); 90 | sst.end(); 91 | }); 92 | 93 | st.test('does not return primitive value', function (sst) { 94 | var Constructor = functionBind.call(thunkify(42), null); 95 | var result = new Constructor(); 96 | sst.notEqual(result, 42); 97 | sst.end(); 98 | }); 99 | 100 | st.test('object from bound constructor is instance of original and bound constructor', function (sst) { 101 | var A = function (x) { 102 | this.name = x || 'A'; 103 | }; 104 | var B = functionBind.call(A, null, 'B'); 105 | 106 | var result = new B(); 107 | sst.ok(result instanceof B, 'result is instance of bound constructor'); 108 | sst.ok(result instanceof A, 'result is instance of original constructor'); 109 | sst.end(); 110 | }); 111 | 112 | st.end(); 113 | }); 114 | 115 | t.end(); 116 | }); 117 | 118 | test('with a context', function (t) { 119 | t.test('with no bound arguments', function (st) { 120 | var args, context; 121 | var boundContext = {}; 122 | var namespace = { 123 | func: functionBind.call(function () { 124 | args = Array.prototype.slice.call(arguments); 125 | context = this; 126 | }, boundContext) 127 | }; 128 | namespace.func(1, 2, 3); 129 | st.equal(context, boundContext, 'binds a context properly'); 130 | st.deepEqual(args, [1, 2, 3], 'supplies passed arguments'); 131 | st.end(); 132 | }); 133 | 134 | t.test('with bound arguments', function (st) { 135 | var args, context; 136 | var boundContext = {}; 137 | var namespace = { 138 | func: functionBind.call(function () { 139 | args = Array.prototype.slice.call(arguments); 140 | context = this; 141 | }, boundContext, 1, 2, 3) 142 | }; 143 | namespace.func(4, 5, 6); 144 | st.equal(context, boundContext, 'binds a context properly'); 145 | st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments'); 146 | st.end(); 147 | }); 148 | 149 | t.test('returns properly', function (st) { 150 | var boundContext = {}; 151 | var args; 152 | var namespace = { 153 | func: functionBind.call(function () { 154 | args = Array.prototype.slice.call(arguments); 155 | return this; 156 | }, boundContext) 157 | }; 158 | var context = namespace.func(1, 2, 3); 159 | st.equal(context, boundContext, 'returned context is bound context'); 160 | st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); 161 | st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); 162 | st.end(); 163 | }); 164 | 165 | t.test('returns properly with bound arguments', function (st) { 166 | var boundContext = {}; 167 | var args; 168 | var namespace = { 169 | func: functionBind.call(function () { 170 | args = Array.prototype.slice.call(arguments); 171 | return this; 172 | }, boundContext, 1, 2, 3) 173 | }; 174 | var context = namespace.func(4, 5, 6); 175 | st.equal(context, boundContext, 'returned context is bound context'); 176 | st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); 177 | st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); 178 | st.end(); 179 | }); 180 | 181 | t.test('passes the correct arguments when called as a constructor', function (st) { 182 | var expected = { name: 'Correct' }; 183 | var namespace = { 184 | Func: functionBind.call(function (arg) { 185 | return arg; 186 | }, { name: 'Incorrect' }) 187 | }; 188 | var returned = new namespace.Func(expected); 189 | st.equal(returned, expected, 'returns the right arg when called as a constructor'); 190 | st.end(); 191 | }); 192 | 193 | t.test('has the new instance\'s context when called as a constructor', function (st) { 194 | var actualContext; 195 | var expectedContext = { foo: 'bar' }; 196 | var namespace = { 197 | Func: functionBind.call(function () { 198 | actualContext = this; 199 | }, expectedContext) 200 | }; 201 | var result = new namespace.Func(); 202 | st.equal(result instanceof namespace.Func, true); 203 | st.notEqual(actualContext, expectedContext); 204 | st.end(); 205 | }); 206 | 207 | t.end(); 208 | }); 209 | 210 | test('bound function length', function (t) { 211 | t.test('sets a correct length without thisArg', function (st) { 212 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }); 213 | st.equal(subject.length, 3); 214 | st.equal(subject(1, 2, 3), 6); 215 | st.end(); 216 | }); 217 | 218 | t.test('sets a correct length with thisArg', function (st) { 219 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}); 220 | st.equal(subject.length, 3); 221 | st.equal(subject(1, 2, 3), 6); 222 | st.end(); 223 | }); 224 | 225 | t.test('sets a correct length without thisArg and first argument', function (st) { 226 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1); 227 | st.equal(subject.length, 2); 228 | st.equal(subject(2, 3), 6); 229 | st.end(); 230 | }); 231 | 232 | t.test('sets a correct length with thisArg and first argument', function (st) { 233 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1); 234 | st.equal(subject.length, 2); 235 | st.equal(subject(2, 3), 6); 236 | st.end(); 237 | }); 238 | 239 | t.test('sets a correct length without thisArg and too many arguments', function (st) { 240 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4); 241 | st.equal(subject.length, 0); 242 | st.equal(subject(), 6); 243 | st.end(); 244 | }); 245 | 246 | t.test('sets a correct length with thisArg and too many arguments', function (st) { 247 | var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4); 248 | st.equal(subject.length, 0); 249 | st.equal(subject(), 6); 250 | st.end(); 251 | }); 252 | }); 253 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [v1.1.2](https://github.com/ljharb/function-bind/compare/v1.1.1...v1.1.2) - 2023-10-12 9 | 10 | ### Merged 11 | 12 | - Point to the correct file [`#16`](https://github.com/ljharb/function-bind/pull/16) 13 | 14 | ### Commits 15 | 16 | - [Tests] migrate tests to Github Actions [`4f8b57c`](https://github.com/ljharb/function-bind/commit/4f8b57c02f2011fe9ae353d5e74e8745f0988af8) 17 | - [Tests] remove `jscs` [`90eb2ed`](https://github.com/ljharb/function-bind/commit/90eb2edbeefd5b76cd6c3a482ea3454db169b31f) 18 | - [meta] update `.gitignore` [`53fcdc3`](https://github.com/ljharb/function-bind/commit/53fcdc371cd66634d6e9b71c836a50f437e89fed) 19 | - [Tests] up to `node` `v11.10`, `v10.15`, `v9.11`, `v8.15`, `v6.16`, `v4.9`; use `nvm install-latest-npm`; run audit script in tests [`1fe8f6e`](https://github.com/ljharb/function-bind/commit/1fe8f6e9aed0dfa8d8b3cdbd00c7f5ea0cd2b36e) 20 | - [meta] add `auto-changelog` [`1921fcb`](https://github.com/ljharb/function-bind/commit/1921fcb5b416b63ffc4acad051b6aad5722f777d) 21 | - [Robustness] remove runtime dependency on all builtins except `.apply` [`f743e61`](https://github.com/ljharb/function-bind/commit/f743e61aa6bb2360358c04d4884c9db853d118b7) 22 | - Docs: enable badges; update wording [`503cb12`](https://github.com/ljharb/function-bind/commit/503cb12d998b5f91822776c73332c7adcd6355dd) 23 | - [readme] update badges [`290c5db`](https://github.com/ljharb/function-bind/commit/290c5dbbbda7264efaeb886552a374b869a4bb48) 24 | - [Tests] switch to nyc for coverage [`ea360ba`](https://github.com/ljharb/function-bind/commit/ea360ba907fc2601ed18d01a3827fa2d3533cdf8) 25 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`cae5e9e`](https://github.com/ljharb/function-bind/commit/cae5e9e07a5578dc6df26c03ee22851ce05b943c) 26 | - [meta] add `funding` field; create FUNDING.yml [`c9f4274`](https://github.com/ljharb/function-bind/commit/c9f4274aa80ea3aae9657a3938fdba41a3b04ca6) 27 | - [Tests] fix eslint errors from #15 [`f69aaa2`](https://github.com/ljharb/function-bind/commit/f69aaa2beb2fdab4415bfb885760a699d0b9c964) 28 | - [actions] fix permissions [`99a0cd9`](https://github.com/ljharb/function-bind/commit/99a0cd9f3b5bac223a0d572f081834cd73314be7) 29 | - [meta] use `npmignore` to autogenerate an npmignore file [`f03b524`](https://github.com/ljharb/function-bind/commit/f03b524ca91f75a109a5d062f029122c86ecd1ae) 30 | - [Dev Deps] update `@ljharb/eslint‑config`, `eslint`, `tape` [`7af9300`](https://github.com/ljharb/function-bind/commit/7af930023ae2ce7645489532821e4fbbcd7a2280) 31 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `covert`, `tape` [`64a9127`](https://github.com/ljharb/function-bind/commit/64a9127ab0bd331b93d6572eaf6e9971967fc08c) 32 | - [Tests] use `aud` instead of `npm audit` [`e75069c`](https://github.com/ljharb/function-bind/commit/e75069c50010a8fcce2a9ce2324934c35fdb4386) 33 | - [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`d03555c`](https://github.com/ljharb/function-bind/commit/d03555ca59dea3b71ce710045e4303b9e2619e28) 34 | - [meta] add `safe-publish-latest` [`9c8f809`](https://github.com/ljharb/function-bind/commit/9c8f8092aed027d7e80c94f517aa892385b64f09) 35 | - [Dev Deps] update `@ljharb/eslint-config`, `tape` [`baf6893`](https://github.com/ljharb/function-bind/commit/baf6893e27f5b59abe88bc1995e6f6ed1e527397) 36 | - [meta] create SECURITY.md [`4db1779`](https://github.com/ljharb/function-bind/commit/4db17799f1f28ae294cb95e0081ca2b591c3911b) 37 | - [Tests] add `npm run audit` [`c8b38ec`](https://github.com/ljharb/function-bind/commit/c8b38ec40ed3f85dabdee40ed4148f1748375bc2) 38 | - Revert "Point to the correct file" [`05cdf0f`](https://github.com/ljharb/function-bind/commit/05cdf0fa205c6a3c5ba40bbedd1dfa9874f915c9) 39 | 40 | ## [v1.1.1](https://github.com/ljharb/function-bind/compare/v1.1.0...v1.1.1) - 2017-08-28 41 | 42 | ### Commits 43 | 44 | - [Tests] up to `node` `v8`; newer npm breaks on older node; fix scripts [`817f7d2`](https://github.com/ljharb/function-bind/commit/817f7d28470fdbff8ef608d4d565dd4d1430bc5e) 45 | - [Dev Deps] update `eslint`, `jscs`, `tape`, `@ljharb/eslint-config` [`854288b`](https://github.com/ljharb/function-bind/commit/854288b1b6f5c555f89aceb9eff1152510262084) 46 | - [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`83e639f`](https://github.com/ljharb/function-bind/commit/83e639ff74e6cd6921285bccec22c1bcf72311bd) 47 | - Only apps should have lockfiles [`5ed97f5`](https://github.com/ljharb/function-bind/commit/5ed97f51235c17774e0832e122abda0f3229c908) 48 | - Use a SPDX-compliant “license” field. [`5feefea`](https://github.com/ljharb/function-bind/commit/5feefea0dc0193993e83e5df01ded424403a5381) 49 | 50 | ## [v1.1.0](https://github.com/ljharb/function-bind/compare/v1.0.2...v1.1.0) - 2016-02-14 51 | 52 | ### Commits 53 | 54 | - Update `eslint`, `tape`; use my personal shared `eslint` config [`9c9062a`](https://github.com/ljharb/function-bind/commit/9c9062abbe9dd70b59ea2c3a3c3a81f29b457097) 55 | - Add `npm run eslint` [`dd96c56`](https://github.com/ljharb/function-bind/commit/dd96c56720034a3c1ffee10b8a59a6f7c53e24ad) 56 | - [New] return the native `bind` when available. [`82186e0`](https://github.com/ljharb/function-bind/commit/82186e03d73e580f95ff167e03f3582bed90ed72) 57 | - [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`a3dd767`](https://github.com/ljharb/function-bind/commit/a3dd76720c795cb7f4586b0544efabf8aa107b8b) 58 | - Update `eslint` [`3dae2f7`](https://github.com/ljharb/function-bind/commit/3dae2f7423de30a2d20313ddb1edc19660142fe9) 59 | - Update `tape`, `covert`, `jscs` [`a181eee`](https://github.com/ljharb/function-bind/commit/a181eee0cfa24eb229c6e843a971f36e060a2f6a) 60 | - [Tests] up to `node` `v5.6`, `v4.3` [`964929a`](https://github.com/ljharb/function-bind/commit/964929a6a4ddb36fb128de2bcc20af5e4f22e1ed) 61 | - Test up to `io.js` `v2.1` [`2be7310`](https://github.com/ljharb/function-bind/commit/2be7310f2f74886a7124ca925be411117d41d5ea) 62 | - Update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`45f3d68`](https://github.com/ljharb/function-bind/commit/45f3d6865c6ca93726abcef54febe009087af101) 63 | - [Dev Deps] update `tape`, `jscs` [`6e1340d`](https://github.com/ljharb/function-bind/commit/6e1340d94642deaecad3e717825db641af4f8b1f) 64 | - [Tests] up to `io.js` `v3.3`, `node` `v4.1` [`d9bad2b`](https://github.com/ljharb/function-bind/commit/d9bad2b778b1b3a6dd2876087b88b3acf319f8cc) 65 | - Update `eslint` [`935590c`](https://github.com/ljharb/function-bind/commit/935590caa024ab356102e4858e8fc315b2ccc446) 66 | - [Dev Deps] update `jscs`, `eslint`, `@ljharb/eslint-config` [`8c9a1ef`](https://github.com/ljharb/function-bind/commit/8c9a1efd848e5167887aa8501857a0940a480c57) 67 | - Test on `io.js` `v2.2` [`9a3a38c`](https://github.com/ljharb/function-bind/commit/9a3a38c92013aed6e108666e7bd40969b84ac86e) 68 | - Run `travis-ci` tests on `iojs` and `node` v0.12; speed up builds; allow 0.8 failures. [`69afc26`](https://github.com/ljharb/function-bind/commit/69afc2617405b147dd2a8d8ae73ca9e9283f18b4) 69 | - [Dev Deps] Update `tape`, `eslint` [`36c1be0`](https://github.com/ljharb/function-bind/commit/36c1be0ab12b45fe5df6b0fdb01a5d5137fd0115) 70 | - Update `tape`, `jscs` [`98d8303`](https://github.com/ljharb/function-bind/commit/98d8303cd5ca1c6b8f985469f86b0d44d7d45f6e) 71 | - Update `jscs` [`9633a4e`](https://github.com/ljharb/function-bind/commit/9633a4e9fbf82051c240855166e468ba8ba0846f) 72 | - Update `tape`, `jscs` [`c80ef0f`](https://github.com/ljharb/function-bind/commit/c80ef0f46efc9791e76fa50de4414092ac147831) 73 | - Test up to `io.js` `v3.0` [`7e2c853`](https://github.com/ljharb/function-bind/commit/7e2c8537d52ab9cf5a655755561d8917684c0df4) 74 | - Test on `io.js` `v2.4` [`5a199a2`](https://github.com/ljharb/function-bind/commit/5a199a27ba46795ba5eaf0845d07d4b8232895c9) 75 | - Test on `io.js` `v2.3` [`a511b88`](https://github.com/ljharb/function-bind/commit/a511b8896de0bddf3b56862daa416c701f4d0453) 76 | - Fixing a typo from 822b4e1938db02dc9584aa434fd3a45cb20caf43 [`732d6b6`](https://github.com/ljharb/function-bind/commit/732d6b63a9b33b45230e630dbcac7a10855d3266) 77 | - Update `jscs` [`da52a48`](https://github.com/ljharb/function-bind/commit/da52a4886c06d6490f46ae30b15e4163ba08905d) 78 | - Lock covert to v1.0.0. [`d6150fd`](https://github.com/ljharb/function-bind/commit/d6150fda1e6f486718ebdeff823333d9e48e7430) 79 | 80 | ## [v1.0.2](https://github.com/ljharb/function-bind/compare/v1.0.1...v1.0.2) - 2014-10-04 81 | 82 | ## [v1.0.1](https://github.com/ljharb/function-bind/compare/v1.0.0...v1.0.1) - 2014-10-03 83 | 84 | ### Merged 85 | 86 | - make CI build faster [`#3`](https://github.com/ljharb/function-bind/pull/3) 87 | 88 | ### Commits 89 | 90 | - Using my standard jscs.json [`d8ee94c`](https://github.com/ljharb/function-bind/commit/d8ee94c993eff0a84cf5744fe6a29627f5cffa1a) 91 | - Adding `npm run lint` [`7571ab7`](https://github.com/ljharb/function-bind/commit/7571ab7dfdbd99b25a1dbb2d232622bd6f4f9c10) 92 | - Using consistent indentation [`e91a1b1`](https://github.com/ljharb/function-bind/commit/e91a1b13a61e99ec1e530e299b55508f74218a95) 93 | - Updating jscs [`7e17892`](https://github.com/ljharb/function-bind/commit/7e1789284bc629bc9c1547a61c9b227bbd8c7a65) 94 | - Using consistent quotes [`c50b57f`](https://github.com/ljharb/function-bind/commit/c50b57fcd1c5ec38320979c837006069ebe02b77) 95 | - Adding keywords [`cb94631`](https://github.com/ljharb/function-bind/commit/cb946314eed35f21186a25fb42fc118772f9ee00) 96 | - Directly export a function expression instead of using a declaration, and relying on hoisting. [`5a33c5f`](https://github.com/ljharb/function-bind/commit/5a33c5f45642de180e0d207110bf7d1843ceb87c) 97 | - Naming npm URL and badge in README; use SVG [`2aef8fc`](https://github.com/ljharb/function-bind/commit/2aef8fcb79d54e63a58ae557c4e60949e05d5e16) 98 | - Naming deps URLs in README [`04228d7`](https://github.com/ljharb/function-bind/commit/04228d766670ee45ca24e98345c1f6a7621065b5) 99 | - Naming travis-ci URLs in README; using SVG [`62c810c`](https://github.com/ljharb/function-bind/commit/62c810c2f54ced956cd4d4ab7b793055addfe36e) 100 | - Make sure functions are invoked correctly (also passing coverage tests) [`2b289b4`](https://github.com/ljharb/function-bind/commit/2b289b4dfbf037ffcfa4dc95eb540f6165e9e43a) 101 | - Removing the strict mode pragmas; they make tests fail. [`1aa701d`](https://github.com/ljharb/function-bind/commit/1aa701d199ddc3782476e8f7eef82679be97b845) 102 | - Adding myself as a contributor [`85fd57b`](https://github.com/ljharb/function-bind/commit/85fd57b0860e5a7af42de9a287f3f265fc6d72fc) 103 | - Adding strict mode pragmas [`915b08e`](https://github.com/ljharb/function-bind/commit/915b08e084c86a722eafe7245e21db74aa21ca4c) 104 | - Adding devDeps URLs to README [`4ccc731`](https://github.com/ljharb/function-bind/commit/4ccc73112c1769859e4ca3076caf4086b3cba2cd) 105 | - Fixing the description. [`a7a472c`](https://github.com/ljharb/function-bind/commit/a7a472cf649af515c635cf560fc478fbe48999c8) 106 | - Using a function expression instead of a function declaration. [`b5d3e4e`](https://github.com/ljharb/function-bind/commit/b5d3e4ea6aaffc63888953eeb1fbc7ff45f1fa14) 107 | - Updating tape [`f086be6`](https://github.com/ljharb/function-bind/commit/f086be6029fb56dde61a258c1340600fa174d1e0) 108 | - Updating jscs [`5f9bdb3`](https://github.com/ljharb/function-bind/commit/5f9bdb375ab13ba48f30852aab94029520c54d71) 109 | - Updating jscs [`9b409ba`](https://github.com/ljharb/function-bind/commit/9b409ba6118e23395a4e5d83ef39152aab9d3bfc) 110 | - Run coverage as part of tests. [`8e1b6d4`](https://github.com/ljharb/function-bind/commit/8e1b6d459f047d1bd4fee814e01247c984c80bd0) 111 | - Run linter as part of tests [`c1ca83f`](https://github.com/ljharb/function-bind/commit/c1ca83f832df94587d09e621beba682fabfaa987) 112 | - Updating covert [`701e837`](https://github.com/ljharb/function-bind/commit/701e83774b57b4d3ef631e1948143f43a72f4bb9) 113 | 114 | ## [v1.0.0](https://github.com/ljharb/function-bind/compare/v0.2.0...v1.0.0) - 2014-08-09 115 | 116 | ### Commits 117 | 118 | - Make sure old and unstable nodes don't fail Travis [`27adca3`](https://github.com/ljharb/function-bind/commit/27adca34a4ab6ad67b6dfde43942a1b103ce4d75) 119 | - Fixing an issue when the bound function is called as a constructor in ES3. [`e20122d`](https://github.com/ljharb/function-bind/commit/e20122d267d92ce553859b280cbbea5d27c07731) 120 | - Adding `npm run coverage` [`a2e29c4`](https://github.com/ljharb/function-bind/commit/a2e29c4ecaef9e2f6cd1603e868c139073375502) 121 | - Updating tape [`b741168`](https://github.com/ljharb/function-bind/commit/b741168b12b235b1717ff696087645526b69213c) 122 | - Upgrading tape [`63631a0`](https://github.com/ljharb/function-bind/commit/63631a04c7fbe97cc2fa61829cc27246d6986f74) 123 | - Updating tape [`363cb46`](https://github.com/ljharb/function-bind/commit/363cb46dafb23cb3e347729a22f9448051d78464) 124 | 125 | ## v0.2.0 - 2014-03-23 126 | 127 | ### Commits 128 | 129 | - Updating test coverage to match es5-shim. [`aa94d44`](https://github.com/ljharb/function-bind/commit/aa94d44b8f9d7f69f10e060db7709aa7a694e5d4) 130 | - initial [`942ee07`](https://github.com/ljharb/function-bind/commit/942ee07e94e542d91798137bc4b80b926137e066) 131 | - Setting the bound function's length properly. [`079f46a`](https://github.com/ljharb/function-bind/commit/079f46a2d3515b7c0b308c2c13fceb641f97ca25) 132 | - Ensuring that some older browsers will throw when given a regex. [`36ac55b`](https://github.com/ljharb/function-bind/commit/36ac55b87f460d4330253c92870aa26fbfe8227f) 133 | - Removing npm scripts that don't have dependencies [`9d2be60`](https://github.com/ljharb/function-bind/commit/9d2be600002cb8bc8606f8f3585ad3e05868c750) 134 | - Updating tape [`297a4ac`](https://github.com/ljharb/function-bind/commit/297a4acc5464db381940aafb194d1c88f4e678f3) 135 | - Skipping length tests for now. [`d9891ea`](https://github.com/ljharb/function-bind/commit/d9891ea4d2aaffa69f408339cdd61ff740f70565) 136 | - don't take my tea [`dccd930`](https://github.com/ljharb/function-bind/commit/dccd930bfd60ea10cb178d28c97550c3bc8c1e07) 137 | --------------------------------------------------------------------------------