René's URL Explorer Experiment


Title: 从underscore源码看如何实现map函数(二) · Issue #14 · webproblem/Blog · GitHub

Open Graph Title: 从underscore源码看如何实现map函数(二) · Issue #14 · webproblem/Blog

X Title: 从underscore源码看如何实现map函数(二) · Issue #14 · webproblem/Blog

Description: 在上篇文章中,遗留了两个问题: arguments 存在性能问题 call 比 apply 速度更快 本篇文章将会对这两个问题进行详细的分析。 arguments 存在性能问题 arguments 是存在于函数内部用于存储传递给函数的参数的类数组对象,在函数被调用时创建。arguments 是类数组对象,只拥有 length 属性,但是可以在函数内部转换为数组。 function test() { var args = Array.prototype.slice.cal...

Open Graph Description: 在上篇文章中,遗留了两个问题: arguments 存在性能问题 call 比 apply 速度更快 本篇文章将会对这两个问题进行详细的分析。 arguments 存在性能问题 arguments 是存在于函数内部用于存储传递给函数的参数的类数组对象,在函数被调用时创建。arguments 是类数组对象,只拥有 length 属性,但是可以在函数内部转换为数组。 function test(...

X Description: 在上篇文章中,遗留了两个问题: arguments 存在性能问题 call 比 apply 速度更快 本篇文章将会对这两个问题进行详细的分析。 arguments 存在性能问题 arguments 是存在于函数内部用于存储传递给函数的参数的类数组对象,在函数被调用时创建。arguments 是类数组对象,只拥有 length 属性,但是可以在函数内部转换为数组。 function test(...

Opengraph URL: https://github.com/webproblem/Blog/issues/14

X: @github

direct link

Domain: patch-diff.githubusercontent.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"从underscore源码看如何实现map函数(二)","articleBody":"在上篇文章中,遗留了两个问题:\r\n\r\n* arguments 存在性能问题\r\n* call 比 apply 速度更快\r\n\r\n本篇文章将会对这两个问题进行详细的分析。\r\n\r\n### arguments 存在性能问题\r\n\r\narguments 是存在于函数内部用于存储传递给函数的参数的类数组对象,在函数被调用时创建。arguments 是类数组对象,只拥有 length 属性,但是可以在函数内部转换为数组。\r\n\r\n```javascript\r\nfunction test() {\r\n    var args = Array.prototype.slice.call(arguments);\r\n    console.log(args); // [\"白展堂\", \"吕秀才\"]\r\n    // var args2 = [].slice.call(arguments);\r\n    // console.log(args2);\r\n}\r\ntest('白展堂', '吕秀才');\r\n```\r\n\r\n但是对参数使用 slice 会阻止某些 JavaScript 引擎中的优化,引发性能问题。所以将 arguments 对象转换为数组应该采用如下方法:\r\n\r\n```javascript\r\nvar args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));\r\nvar args = Array.from(arguments);\r\nvar args = [...arguments];\r\n```\r\n\r\n我们来测试下,性能差距究竟有多大。\r\n\r\n```javascript\r\nfunction sum() {\r\n\tvar args = Array.prototype.slice.call(arguments);\r\n\treturn args;\r\n}\r\nfunction sum1() {  \r\n    var args = Array.apply(null, arguments); \r\n\treturn args;\r\n}\r\nfunction leaksArguments(number) {\r\n\tvar t = new Date;\r\n\tfor(var i=0; i\u003c100000; i++) {\r\n\t\tif(!number) {\r\n\t\t\tsum(1,2,3,4,5,6);\r\n\t\t}else {\r\n\t\t\tsum1(1,2,3,4,5,6);\r\n\t\t}\r\n\t}\r\n\tconsole.log(`耗时:${new Date - t}`);\r\n}\r\n```\r\n\r\n简单写了一个测试用例,分别得出两种将 arguments 对象转换成数组的方法的耗时情况,执行 leaksArguments 函数时不传参数使用的是 Array.prototype.slice.call 方式转换,传参使用的是  Array.apply 方式转换。测试结果如下:\r\n\r\n![image](https://user-images.githubusercontent.com/20440496/49202648-3ad40f00-f3e0-11e8-8b85-ab3df31fc69a.png)\r\n\r\n可以看到,性能提升了2倍多,且随着传递给函数的参数越多,性能耗时差距就越大。这也说明,JavaScript 引擎在访问 arguments 时会消耗性能。\r\n\r\n那么如何安全地使用 `arguments` 呢?\r\n\r\n* 只使用 `arguments.length` 属性。\r\n* 只是用 `arguments[i] ` ,需要始终为 arguments 的合法整型索引,且不允许越界 。\r\n* 除了 `.length` 和 `[i]`,不要直接使用 `arguments`。\r\n* 严格来说用 `fn.apply(y, arguments)` 是没问题的,但除此之外都不行(例如 `.slice`)。 `Function#apply` 是特别的存在。\r\n* 请注意,给函数添加属性值(例如 `fn.$inject = ...`)和绑定函数(即 `Function#bind` 的结果)会生成隐藏类,因此此时使用 `#apply` 不安全。\r\n\r\n如果按照上面的方式正确使用 arguments 对象,就不必担心使用 arguments 导致性能消耗问题。\r\n\r\n### call 比 apply 速度更快\r\n\r\ncall 和 apply 实现的功能都是一样的,都是为了改变函数在运行时的上下文,只是接收的参数方式不同,call 方法从第二个参数开始是一系列参数列表,而 apply 方法则是把参数放在数组里。\r\n\r\n为了证明 call 的速度比 apply 更快,来写一个简单的测试。\r\n\r\n```javascript\r\nvar foo = {\r\n    color: 'blue'\r\n}\r\nfunction bar(name) {\r\n    return name + this.color;\r\n}\r\nfunction test(number) {\r\n\tvar t = new Date;\r\n\tfor(var i=0; i\u003c 100000; i++) {\r\n\t\tif(!number) {\r\n\t\t\tbar.call(foo, '天空的颜色');\r\n\t\t}else {\r\n\t\t\tbar.apply(foo, ['天空的颜色']);\r\n\t\t}\r\n\t}\r\n\tconsole.log(`${!number?'call':'apply'}耗时:${new Date - t}`);\r\n}\r\n```\r\n\r\n测试结果如下:\r\n\r\n![image](https://user-images.githubusercontent.com/20440496/49208566-12a1db80-f3f3-11e8-9c2b-897adcdbee06.png)\r\n\r\n当然,可以推荐在一个性能测试网站 [jsperf](https://jsperf.com/) 上进行性能测试。下面是几个简单的测试结果。\r\n\r\n![image](https://user-images.githubusercontent.com/20440496/49208783-a5db1100-f3f3-11e8-9d25-66b020fe9193.png)\r\n\r\n![image](https://user-images.githubusercontent.com/20440496/49208800-af647900-f3f3-11e8-8810-11f5d61217dc.png)\r\n\r\n想要知道 call 和 apply 在性能上为什么会有差异,就得知道 call 和 apply 在执行过程中发生了什么。简单来说就是 call 和 apply,最终都是调用一个叫做 `[[Call]]` 的内部函数 ,apply 方法执行过程中对参数的处理更为复杂,需要进行检测数组参数和格式化等步骤,而 call 方式的参数原本就是按照顺序排列的参数列表,处理步骤更为简洁。 关于具体的执行步骤可参见 [stackoverflow 的回答](https://stackoverflow.com/questions/23769556/why-is-call-so-much-faster-than-apply)。\r\n\r\n需要知道的是,关于 call 和 apply 性能差异问题也只是存在于 ES6 之前,随着 ECMAScript 语言和 JavaScript 解释器性能不断增强,call 和 apply 性能大致一样了。call 和 apply 是存在于不同场景下的,我们应该更加注重两个函数在实际应用场景中如何选择合适的方式来实现需求的效果。\r\n\r\n### 参考\r\n\r\n* [V8 性能优化杀手](https://juejin.im/post/5959edfc5188250d83241399#heading-6)\r\n\r\n* [arguments、callee、caller,的性能实验](https://www.web-tinker.com/article/20298.html)\r\n\r\n* https://zhuanlan.zhihu.com/p/27659836","author":{"url":"https://github.com/webproblem","@type":"Person","name":"webproblem"},"datePublished":"2018-11-27T13:17:18.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/14/Blog/issues/14"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:c674cc1c-dd1e-953c-4628-46d9daf0945e
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-idC872:25602F:91FB823:BE854E7:6975BA88
html-safe-nonce7f17ef0990058c536af8d24addc561f744754cab11db48f0dee99df09e974431
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDODcyOjI1NjAyRjo5MUZCODIzOkJFODU0RTc6Njk3NUJBODgiLCJ2aXNpdG9yX2lkIjoiMzM0NzA0NjY5OTYxOTQzMzA5NiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmac153095776e3e55ae0dc0b548cfe7cdbdb00cc1e1fa47c921e9c280b616674a0a
hovercard-subject-tagissue:384790307
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/webproblem/Blog/14/issue_layout
twitter:imagehttps://opengraph.githubassets.com/cc95da3a7ab34f7a8f397fd4a0c8b16fa5c13fac6c5590341ddfefa61d47394c/webproblem/Blog/issues/14
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/cc95da3a7ab34f7a8f397fd4a0c8b16fa5c13fac6c5590341ddfefa61d47394c/webproblem/Blog/issues/14
og:image:alt在上篇文章中,遗留了两个问题: arguments 存在性能问题 call 比 apply 速度更快 本篇文章将会对这两个问题进行详细的分析。 arguments 存在性能问题 arguments 是存在于函数内部用于存储传递给函数的参数的类数组对象,在函数被调用时创建。arguments 是类数组对象,只拥有 length 属性,但是可以在函数内部转换为数组。 function test(...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamewebproblem
hostnamegithub.com
expected-hostnamegithub.com
None4a4bf5f4e28041a9d2e5c107d7d20b78b4294ba261cab243b28167c16a623a1f
turbo-cache-controlno-preview
go-importgithub.com/webproblem/Blog git https://github.com/webproblem/Blog.git
octolytics-dimension-user_id20440496
octolytics-dimension-user_loginwebproblem
octolytics-dimension-repository_id115346710
octolytics-dimension-repository_nwowebproblem/Blog
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id115346710
octolytics-dimension-repository_network_root_nwowebproblem/Blog
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release488b30e96dfd057fbbe44c6665ccbc030b729dde
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://patch-diff.githubusercontent.com/webproblem/Blog/issues/14#start-of-content
https://patch-diff.githubusercontent.com/
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Fwebproblem%2FBlog%2Fissues%2F14
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Fwebproblem%2FBlog%2Fissues%2F14
Sign up https://patch-diff.githubusercontent.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=webproblem%2FBlog
Reloadhttps://patch-diff.githubusercontent.com/webproblem/Blog/issues/14
Reloadhttps://patch-diff.githubusercontent.com/webproblem/Blog/issues/14
Reloadhttps://patch-diff.githubusercontent.com/webproblem/Blog/issues/14
webproblem https://patch-diff.githubusercontent.com/webproblem
Bloghttps://patch-diff.githubusercontent.com/webproblem/Blog
Notifications https://patch-diff.githubusercontent.com/login?return_to=%2Fwebproblem%2FBlog
Fork 15 https://patch-diff.githubusercontent.com/login?return_to=%2Fwebproblem%2FBlog
Star 113 https://patch-diff.githubusercontent.com/login?return_to=%2Fwebproblem%2FBlog
Code https://patch-diff.githubusercontent.com/webproblem/Blog
Issues 10 https://patch-diff.githubusercontent.com/webproblem/Blog/issues
Pull requests 0 https://patch-diff.githubusercontent.com/webproblem/Blog/pulls
Actions https://patch-diff.githubusercontent.com/webproblem/Blog/actions
Projects 0 https://patch-diff.githubusercontent.com/webproblem/Blog/projects
Security 0 https://patch-diff.githubusercontent.com/webproblem/Blog/security
Insights https://patch-diff.githubusercontent.com/webproblem/Blog/pulse
Code https://patch-diff.githubusercontent.com/webproblem/Blog
Issues https://patch-diff.githubusercontent.com/webproblem/Blog/issues
Pull requests https://patch-diff.githubusercontent.com/webproblem/Blog/pulls
Actions https://patch-diff.githubusercontent.com/webproblem/Blog/actions
Projects https://patch-diff.githubusercontent.com/webproblem/Blog/projects
Security https://patch-diff.githubusercontent.com/webproblem/Blog/security
Insights https://patch-diff.githubusercontent.com/webproblem/Blog/pulse
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/webproblem/Blog/issues/14
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/webproblem/Blog/issues/14
从underscore源码看如何实现map函数(二)https://patch-diff.githubusercontent.com/webproblem/Blog/issues/14#top
JavaScripthttps://github.com/webproblem/Blog/issues?q=state%3Aopen%20label%3A%22JavaScript%22
underscorehttps://github.com/webproblem/Blog/issues?q=state%3Aopen%20label%3A%22underscore%22
https://github.com/webproblem
https://github.com/webproblem
webproblemhttps://github.com/webproblem
on Nov 27, 2018https://github.com/webproblem/Blog/issues/14#issue-384790307
https://user-images.githubusercontent.com/20440496/49202648-3ad40f00-f3e0-11e8-8b85-ab3df31fc69a.png
https://user-images.githubusercontent.com/20440496/49208566-12a1db80-f3f3-11e8-9c2b-897adcdbee06.png
jsperfhttps://jsperf.com/
https://user-images.githubusercontent.com/20440496/49208783-a5db1100-f3f3-11e8-9d25-66b020fe9193.png
https://user-images.githubusercontent.com/20440496/49208800-af647900-f3f3-11e8-8810-11f5d61217dc.png
stackoverflow 的回答https://stackoverflow.com/questions/23769556/why-is-call-so-much-faster-than-apply
V8 性能优化杀手https://juejin.im/post/5959edfc5188250d83241399#heading-6
arguments、callee、caller,的性能实验https://www.web-tinker.com/article/20298.html
https://zhuanlan.zhihu.com/p/27659836https://zhuanlan.zhihu.com/p/27659836
JavaScripthttps://github.com/webproblem/Blog/issues?q=state%3Aopen%20label%3A%22JavaScript%22
underscorehttps://github.com/webproblem/Blog/issues?q=state%3Aopen%20label%3A%22underscore%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.