Help
RSS
API
Feed
Maltego
Contact
Domain > nazomikan.hateblo.jp
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2015-01-11
54.64.13.59
(
ClassC
)
2025-12-09
3.175.34.65
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: CloudFrontDate: Tue, 09 Dec 2025 08:47:39 GMTContent-Type: text/htmlContent-Length: 167Connection: keep-aliveLocation: https://nazomikan.hateblo.jp/X-Cache: Redirect from cloudfrontVia: 1.1 240505787baa09e4b0a287e248b4543a.cloudfront.net (CloudFront)X-Amz-Cf-Pop: HIO52-P3X-Amz-Cf-Id: 7EGqJ_06llmcU1KTPSBndM2LrYld2Sp6sy3x2UuLhsXSgy1yPfeoqg html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>CloudFront/center>/body>/html>
Port 443
HTTP/1.1 200 OKContent-Type: text/html; charsetutf-8Transfer-Encoding: chunkedConnection: keep-aliveServer: nginxDate: Tue, 09 Dec 2025 08:47:39 GMTCache-Control: privateX-Proxy-Revision: a9c7d634032ae4419eb72f1520ec876ac061836fVary: Accept-EncodingVary: X-Epic-Device-Type,X-Epic-Flag-Variants,Accept-EncodingAccess-Control-Allow-Origin: *Content-Security-Policy: frame-ancestors none; upgrade-insecure-requestsContent-Security-Policy-Report-Only: block-all-mixed-content; report-uri https://blog.hatena.ne.jp/api/csp_reportP3P: CPOTI CUR OUR BUS STAX-Cache-Only-Varnish: 1X-Content-Type-Options: nosniffX-Dispatch: Hatena::Epic::Web::Blogs::Index#indexX-Frame-Options: DENYX-Revision: a9c7d634032ae4419eb72f1520ec87X-XSS-Protection: 1X-Runtime: 0.205627X-Varnish: 7145313 22068151Via: 1.1 ip-10-1-19-41.ap-northeast-1.compute.internal (Varnish/7.6), 1.1 0b56b2a6b0fdc99543294439c61ded5e.cloudfront.net (CloudFront)Strict-Transport-Security: max-age2592000;X-Cache: Miss from cloudfrontX-Amz-Cf-Pop: HIO52-P3X-Amz-Cf-Id: rysCQLmM3W3hXlznfSjf_HqHvA8D_VYNmM212KHyFCXwPw6l9ItcHgAge: 1307 !DOCTYPE html>html langjadata-admin-domain//blog.hatena.ne.jpdata-admin-originhttps://blog.hatena.ne.jpdata-authornazomikandata-avail-langsja endata-blognazomikan.hateblo.jpdata-blog-hostnazomikan.hateblo.jpdata-blog-is-public1data-blog-nameぶれすとつーるdata-blog-ownernazomikandata-blog-show-ads1data-blog-show-sleeping-ads1data-blog-urihttps://nazomikan.hateblo.jp/data-blog-uuid13208692334729898413data-blogs-uri-basehttps://nazomikan.hateblo.jpdata-brandhatenablogdata-data-layer{"hatenablog":{"admin":{},"analytics":{"brand_property_id":"","measurement_id":"","non_sampling_property_id":"","property_id":"UA-5945415-3","separated_property_id":"UA-29716941-26"},"blog":{"blog_id":"13208692334729898413","content_seems_japanese":"true","disable_ads":"","enable_ads":"true","enable_keyword_link":"true","entry_show_footer_related_entries":"true","force_pc_view":"false","is_public":"true","is_responsive_view":"false","is_sleeping":"true","lang":"ja","name":"\u3076\u308c\u3059\u3068\u3064\u30fc\u308b","owner_name":"nazomikan","uri":"https://nazomikan.hateblo.jp/"},"brand":"hatenablog","page_id":"index","permalink_entry":null,"pro":"free","router_type":"blogs"}}data-devicepcdata-dont-recommend-profalsedata-global-domainhttps://hatena.blogdata-globalheader-colorbdata-globalheader-typepcdata-has-touch-view1data-help-urlhttps://help.hatenablog.comdata-pageindexdata-parts-domainhttps://hatenablog-parts.comdata-plus-availabledata-profalsedata-router-typeblogsdata-sentry-dsnhttps://03a33e4781a24cf2885099fed222b56d@sentry.io/1195218data-sentry-environmentproductiondata-sentry-sample-rate0.1data-static-domainhttps://cdn.blog.st-hatena.comdata-versiona9c7d634032ae4419eb72f1520ec87 data-initial-state{} > head prefixog: http://ogp.me/ns# fb: http://ogp.me/ns/fb#> meta namerobots contentmax-image-preview:large /> meta charsetutf-8/> meta http-equivX-UA-Compatible contentIE7; IE9; IE10; IE11 /> title>ぶれすとつーる/title> link relcanonical hrefhttps://nazomikan.hateblo.jp//> meta itempropname contentぶれすとつーる/> meta itempropimage contenthttps://cdn.blog.st-hatena.com/images/theme/og-image-1500.png/> meta propertyog:title contentぶれすとつーる/>meta propertyog:type contentblog/> meta propertyog:url contenthttps://nazomikan.hateblo.jp//> meta propertyog:image contenthttps://cdn.blog.st-hatena.com/images/theme/og-image-1500.png/>meta propertyog:image:alt contentぶれすとつーる/> meta propertyog:description contentだいたいjavascript />meta propertyog:site_name contentぶれすとつーる/> meta nametwitter:card contentsummary_large_image /> meta nametwitter:image contenthttps://cdn.blog.st-hatena.com/images/theme/og-image-1500.png /> meta nametwitter:title contentぶれすとつーる /> meta nametwitter:description contentだいたいjavascript /> meta nametwitter:app:name:iphone contentはてなブログアプリ /> meta nametwitter:app:id:iphone content583299321 /> meta nametwitter:app:url:iphone contenthatenablog:///open?urihttps%3A%2F%2Fnazomikan.hateblo.jp%2F /> meta nametwitter:site content@nazomikan /> meta namedescription contentだいたいjavascript /> meta namegoogle-site-verification contentad3a8lUHg0UY_R4Y6Ts67OkkhJVdW0UT_OHC1TFBIus /> meta namekeywords contentnazomikan, javascript, ecmascript /> script idembed-gtm-data-layer-loader data-data-layer-page-specific>(function() { function loadDataLayer(elem, attrName) { if (!elem) { return {}; } var json elem.getAttribute(attrName); if (!json) { return {}; } return JSON.parse(json); } var globalVariables loadDataLayer( document.documentElement, data-data-layer ); var pageSpecificVariables loadDataLayer( document.getElementById(embed-gtm-data-layer-loader), data-data-layer-page-specific ); var variables globalVariables, pageSpecificVariables; if (!window.dataLayer) { window.dataLayer ; } for (var i 0; i variables.length; i++) { window.dataLayer.push(variablesi); }})();/script>!-- Google Tag Manager -->script>(function(w,d,s,l,i){wlwl||;wl.push({gtm.start:new Date().getTime(),event:gtm.js});var fd.getElementsByTagName(s)0,jd.createElement(s),dll!dataLayer?&l+l:;j.asynctrue;j.srchttps://www.googletagmanager.com/gtm.js?id+i+dl;f.parentNode.insertBefore(j,f);})(window,document,script,dataLayer,GTM-P4CXTW);/script>!-- End Google Tag Manager --> link relshortcut icon hrefhttps://nazomikan.hateblo.jp/icon/favicon>link relapple-touch-icon hrefhttps://nazomikan.hateblo.jp/icon/touch>link relicon sizes192x192 hrefhttps://nazomikan.hateblo.jp/icon/link> link relalternate typeapplication/atom+xml titleAtom hrefhttps://nazomikan.hateblo.jp/feed/>link relalternate typeapplication/rss+xml titleRSS2.0 hrefhttps://nazomikan.hateblo.jp/rss/> link relauthor hrefhttp://www.hatena.ne.jp/nazomikan/> link relstylesheet typetext/css hrefhttps://cdn.blog.st-hatena.com/css/blog.css?versiona9c7d634032ae4419eb72f1520ec87/> link relstylesheet typetext/css hrefhttps://usercss.blog.st-hatena.com/blog_style/13208692334729898413/35c94502327eaa2eb283dd057e53fbc2a40bf57a/> script> /script> style> div#google_afc_user, div.google-afc-user-container, div.google_afc_image, div.google_afc_blocklink { display: block !important; }/style> script srchttps://cdn.pool.st-hatena.com/valve/valve.js async>/script>script idtest-valve-definition> var valve window.valve || ; valve.push(function(v) { v.config({ service: blog, content: { result: adtrust, documentIds: blog:entry:10328749687194392235,blog:entry:8454420450094638560,blog:entry:8454420450077837664,blog:entry:8454420450077706830,blog:entry:8454420450077637911,blog:entry:12921228815731895097,blog:entry:12921228815725534958 } }); v.defineDFPSlot({sizes:300,250,336,280,slotId:google_afc_user_container_0,unit:/4374287/blo_pc_com_6_3328_0_no}); v.defineDFPSlot({lazy:1,sizes:{mappings:320,568,336,280,300,250,fluid,0,0,300,250},slotId:sleeping-ad-in-entry,unit:/4374287/blog_pc_entry_sleep_in-article}); v.defineDFPSlot({lazy:,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_1,unit:/4374287/blog_user}); v.defineDFPSlot({lazy:,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_2,unit:/4374287/blog_user_2nd}); v.defineDFPSlot({lazy:,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_3,unit:/4374287/blog_user_2nd}); v.defineDFPSlot({lazy:1,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_4,unit:/4374287/blog_user_2nd}); v.defineDFPSlot({lazy:1,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_5,unit:/4374287/blog_user_2nd}); v.defineDFPSlot({lazy:1,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_6,unit:/4374287/blog_user_2nd}); v.defineDFPSlot({lazy:1,sizes:300,250,336,280,468,60,fluid,slotId:google_afc_user_container_7,unit:/4374287/blog_user_2nd}); v.sealDFPSlots(); });/script> script typeapplication/ld+json>{@context:https://schema.org,@type:WebSite,name:ぶれすとつーる,url:https://nazomikan.hateblo.jp/}/script> /head> body classpage-index globalheader-ng-enabled> div idglobalheader-container data-brandhatenablog > iframe idglobalheader height37 frameborder0 allowTransparencytrue>/iframe>/div> nav class blog-controlls > div classblog-controlls-blog-icon> a hrefhttps://nazomikan.hateblo.jp/> img srchttps://cdn.image.st-hatena.com/image/square/2d93421ee8e17e776a21e2ba5cf8156cb1037f63/backendimagemagick;height128;version1;width128/https%3A%2F%2Fcdn.user.blog.st-hatena.com%2Fcustom_blog_icon%2F7401858%2F151424748738795 altぶれすとつーる/> /a> /div> div classblog-controlls-title> a hrefhttps://nazomikan.hateblo.jp/>ぶれすとつーる/a> /div> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_sourceblogs_topright_button&utm_mediumbutton&utm_campaignsubscribe_blog classblog-controlls-subscribe-btn test-blog-header-controlls-subscribe> 読者になる /a> /nav> div idcontainer> div idcontainer-inner> header idblog-title data-brandhatenablog> div idblog-title-inner > div idblog-title-content> h1 idtitle>a hrefhttps://nazomikan.hateblo.jp/>ぶれすとつーる/a>/h1> h2 idblog-description>だいたいjavascript/h2> /div> /div>/header> div idcontent classhfeed > div idcontent-inner> div idwrapper> div idmain> div idmain-inner> article classentry no-entry sleeping-ads styledisplay: block !important;> div classentry-inner> div classentry-content> div classvariable-mobileWeb-ad> div idgoogle_afc_user_container_0 classsleeping-ad styledisplay: block !important;>/div> /div> p classsleeping-ads-notice styledisplay: none;>この広告は、90日以上更新していないブログに表示しています。/p> /div> /div> /article> !-- google_ad_section_start --> !-- rakuten_ad_target_begin --> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-800 words-100 mode-markdown entry-odd identry-10328749687194392235 data-keyword-campaign data-uuid10328749687194392235 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2016/11/14 relnofollow> time datetime2016-11-14T13:55:09Z title2016-11-14T13:55:09Z> span classdate-year>2016/span>span classhyphen>-/span>span classdate-month>11/span>span classhyphen>-/span>span classdate-day>14/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509 classentry-title-link bookmark>CSS&FP WG/a>/h1> /header> div classentry-content hatenablog-entry> p>本記事、ただの用語メモ。/p>p>a classkeyword hrefhttp://d.hatena.ne.jp/keyword/css>css/a>の仕様しらべてたら「a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a>&FP WGによって定められた〜」みたいに書いてあって、そういえばよく見るけどFP is 何?ってなったので調べてた時のメモ/p>p>FP Formatting Properties./p>p>らしい。/p>p>a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a>&FP WG a classkeyword hrefhttp://d.hatena.ne.jp/keyword/Cascading%20Style%20Sheets>Cascading Style Sheets/a> and Formatting Properties Working Group/p>p>がWG名らしい。/p>p>最近の動向まとめたページみてたら/p>p>a hrefhttps://www.w3.org/Style/Activity>Style Activity Statement/a>/p>blockquote>p>Summary of Activity StructureSee the a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a> a hrefhttps://www.w3.org/Style/CSS/>Home Page/a> for up-to-date information about a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a> and the specifications by the a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a> Working Group./p>p>The Working Group was called “a classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a> & FP WG” from 1997 to 2000./p>/blockquote>p>って書いてあったので2000年以前の呼名だったみたいで今はa classkeyword hrefhttp://d.hatena.ne.jp/keyword/CSS>CSS/a> WGらしい。/p>p>公式はここっぽい/p>p>iframe src//hatenablog-parts.com/embed?urlhttps%3A%2F%2Fwww.w3.org%2FStyle%2FCSS%2Fmembers titleCSS WG members classembed-card embed-webcard scrollingno frameborder0 styledisplay: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;>/iframe>cite classhatena-citation>a hrefhttps://www.w3.org/Style/CSS/members>www.w3.org/a>/cite>/p> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509>time data-relative datetime2016-11-14T13:55:09Z title2016-11-14T13:55:09Z classupdated>2016-11-14 22:55/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_mediumbutton&utm_sourceblogs_entry_footer&utm_campaignsubscribe_blog> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509 data-hatena-star-titleCSS&FP WG data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2016/11/14/225509 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?textCSS%26FP+WG+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2016%2F11%2F14%2F225509 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> div idgoogle_afc_user_container_1 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-1600 words-200 mode-markdown entry-even identry-8454420450094638560 data-keyword-campaign data-uuid8454420450094638560 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2015/05/17 relnofollow> time datetime2015-05-16T15:07:55Z title2015-05-16T15:07:55Z> span classdate-year>2015/span>span classhyphen>-/span>span classdate-month>05/span>span classhyphen>-/span>span classdate-day>17/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755 classentry-title-link bookmark> exotic objectがhost objectの呼び名が変わったものという風潮/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/ECMAScript classentry-category-link category-ECMAScript>ECMAScript/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/javascript classentry-category-link category-javascript>javascript/a> /div> /header> div classentry-content hatenablog-entry> ul>li>native object -> ordinary object/li>li>host object -> exotic object/li>/ul>p>って感じの解釈をよく聞くけど違うと思う。(誰も言ってなかったらごめんなさい)/p>h2>es6上での定義/h2>blockquote>p>4.3.6 ordinary object/p>p>object that has the default behaviour for the essential internal methods that must be supported by all objects./p>p>4.3.7 exotic object/p>p>object that does not have the default behaviour for one or more of the essential internal methods that must be supported by all objects./p>p>NOTE Any object that is not an ordinary object is an exotic object./p>/blockquote>p>a hrefhttp://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object>http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object/a>/p>p>全てのオブジェクトが持ってる必須な内部a classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9>メソッド/a>の振る舞いがデフォルトなやつがordinary object/p>p>それ以外(内部a classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9>メソッド/a>の振る舞いがデフォルトじゃないやつ)がexotic object/p>p>ってなってるはず。/p>h2>es5.1の定義/h2>blockquote>p>4.3.6 native object/p>p>object in an a classkeyword hrefhttp://d.hatena.ne.jp/keyword/ECMAScript>ECMAScript/a> implementation whose semantics are fully defined by this specification rather than by the host environment/p>p>NOTE Standard native objects are defined in this specification. Some native objects are built-in; others may be constructed during the course of execution of an a classkeyword hrefhttp://d.hatena.ne.jp/keyword/ECMAScript>ECMAScript/a> program./p>p>4.3.8 host object/p>p>object supplied by the host environment to complete the execution environment of a classkeyword hrefhttp://d.hatena.ne.jp/keyword/ECMAScript>ECMAScript/a>/p>p>NOTE Any object that is not native is a host object./p>/blockquote>p>a hrefhttp://www.ecma-international.org/ecma-262/5.1/#sec-4.3.6>http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.6/a>/p>p>となっていて実行環境ごとに作られるのがhost objectで、そうでないesによって実装されてるのがnative object./p>h2>なので/h2>p>たとえばArrayとかはES5の定義ではnative objectだと思うんだけど、ES6の定義ではcode>DefineOwnProperty/code>がcode>length/code>を考慮するように変更されててデフォルトの振る舞いと違うのでexotic objectになる/p>p>a hrefhttp://people.mozilla.org/~jorendorff/es6-draft.html#sec-array-exotic-objects>http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array-exotic-objects/a>/p>blockquote>p>An Array object is an exotic object/p>/blockquote> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755>time data-relative datetime2015-05-16T15:07:55Z title2015-05-16T15:07:55Z classupdated>2015-05-17 00:07/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_campaignsubscribe_blog&utm_mediumbutton&utm_sourceblogs_entry_footer> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755 data-hatena-star-title exotic objectがhost objectの呼び名が変わったものという風潮 data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2015/05/17/000755 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?text+exotic+object%E3%81%8Chost+object%E3%81%AE%E5%91%BC%E3%81%B3%E5%90%8D%E3%81%8C%E5%A4%89%E3%82%8F%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE%E3%81%A8%E3%81%84%E3%81%86%E9%A2%A8%E6%BD%AE+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2015%2F05%2F17%2F000755 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> div idgoogle_afc_user_container_2 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-6800 words-600 mode-markdown entry-odd identry-8454420450077837664 data-keyword-campaign data-uuid8454420450077837664 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2014/12/23 relnofollow> time datetime2014-12-23T12:27:41Z title2014-12-23T12:27:41Z> span classdate-year>2014/span>span classhyphen>-/span>span classdate-month>12/span>span classhyphen>-/span>span classdate-day>23/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741 classentry-title-link bookmark>requireの仕組み/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/Node classentry-category-link category-Node>Node/a> /div> /header> div classentry-content hatenablog-entry> p>こんばんは/p>p>この記事は Node.js Advent Calender 2014の23日目の記事です。/p>p>iframe srchttp://hatenablog.com/embed?urlhttp%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2014%2Fnodejs titleNode.js Advent Calendar 2014 - Qiita classembed-card embed-webcard scrollingno frameborder0 stylewidth: 100%; height: 155px; max-width: 500px; margin: 10px 0px;>a hrefhttp://qiita.com/advent-calendar/2014/nodejs>Node.js Advent Calendar 2014 - Qiita/a>/iframe>/p>p>a hrefhttp://qiita.com/advent-calendar/2014/nodejs>Node.js Advent Calendar 2014 - Qiita/a>/p>p>普段node書くとき、何気なく使ってるrequireだけど、どんな風にモジュールが読み込まれてるのかコアコードの中を追ってみる。/p>p>a hrefhttps://github.com/joyent/node/blob/v0.11.14/lib/module.js#L362>https://github.com/joyent/node/blob/v0.11.14/lib/module.js#L362/a>/p>pre classcode lang-javascript data-langjavascript data-unlink>Module.prototype.require span classsynIdentifier>function/span>(path) span classsynIdentifier>{/span> assert(util.isString(path), span classsynConstant>path must be a string/span>); assert(path, span classsynConstant>missing path/span>); span classsynStatement>return/span> Module._load(path, span classsynIdentifier>this/span>);span classsynIdentifier>}/span>;/pre>p>こいつが各moduleが読み込まれた時にセットされるrequireの本体。/p>p>簡単なパラメータチェックをしてModule._loadに処理を渡している。/p>p>この時はまだpathのresolveなどはまだしていない。 単純な移譲。/p>h2>module._load/h2>pre classcode lang-javascript data-langjavascript data-unlink>Module._load span classsynIdentifier>function/span>(request, span classsynStatement>parent/span>, isMain) span classsynIdentifier>{/span> span classsynComment>// ...省略/span> span classsynComment>// A/span> span classsynIdentifier>var/span> filename Module._resolveFilename(request, span classsynStatement>parent/span>); span classsynComment>// B/span> span classsynIdentifier>var/span> cachedModule Module._cachespan classsynIdentifier>/span>filenamespan classsynIdentifier>/span>; span classsynStatement>if/span> (cachedModule) span classsynIdentifier>{/span> span classsynStatement>return/span> cachedModule.exports; span classsynIdentifier>}/span> span classsynComment>// C/span> span classsynStatement>if/span> (NativeModule.exists(filename)) span classsynIdentifier>{/span> span classsynComment>//...省略/span> span classsynStatement>return/span> NativeModule.require(filename); span classsynIdentifier>}/span> span classsynComment>// D/span> span classsynIdentifier>var/span> module span classsynStatement>new/span> Module(filename, span classsynStatement>parent/span>); span classsynComment>// ...省略/span> Module._cachespan classsynIdentifier>/span>filenamespan classsynIdentifier>/span> module; span classsynComment>// E/span> span classsynIdentifier>var/span> hadException span classsynConstant>true/span>; span classsynStatement>try/span> span classsynIdentifier>{/span> module.load(filename); hadException span classsynConstant>false/span>; span classsynIdentifier>}/span> span classsynStatement>finally/span> span classsynIdentifier>{/span> span classsynStatement>if/span> (hadException) span classsynIdentifier>{/span> span classsynStatement>delete/span> Module._cachespan classsynIdentifier>/span>filenamespan classsynIdentifier>/span>; span classsynIdentifier>}/span> span classsynIdentifier>}/span> span classsynStatement>return/span> module.exports;span classsynIdentifier>}/span>;/pre>h3>A/h3>p>ここで初めてファイル名の解決が行われます。/p>p>code>Module._resolveFilename/code>というa classkeyword hrefhttp://d.hatena.ne.jp/keyword/API>API/a>を使ってパスを解決しています。/p>p>このa classkeyword hrefhttp://d.hatena.ne.jp/keyword/API>API/a>は第二引数のcode>parent/code> (requireを実行しているmodule自身)のパスから相対的に解決していきます(native moduleを除く)/p>h3>B/h3>p>ファイルのパスが先ほどの手順で解決されているのでこれをキーとして、すでにそのモジュールが読み込まれていてキャッシュが存在していればそれのcode>exports/code>を返すというような実装になってます。/p>p>code>Module._cache/code>はfile名をキー、値にはmodule自身をつっこんでるキャッシュ用のオブジェクトです。/p>p>ここで注意したいのは返してるのはcode>module.exports/code>の値だけです。/p>p>通常ロードされたモジュールに展開されるローカル変数code>module/code>はその呼び出し元moduleのcode>parent/code>プロパティ(a hrefhttp://nodejs.jp/nodejs.org_ja/api/modules.html#modules_module_parent>http://nodejs.jp/nodejs.org_ja/api/modules.html#modules_module_parent/a>)をもってるはずですが、この辺はrequireの度に設定されなおしたりはしません。/p>p>なのでspan stylecolor: #ff0000>code>module.parent/code>をたよりにした実装してるとこの辺でいつか死ぬ/span>のでやめといたほうがいい。/p>p>以前死にました。( a hrefhttps://github.com/joyent/node/issues/6149>module.parent.filename is cached. · Issue #6149 · joyent/node · GitHub/a> )/p>h3>C/h3>p>ロード対象にされてるモジュールがnativeなモジュール(pathとかfsとかそういうやつ)かどうかを判定し、そうであればnativeモジュール用のローダーで読み込みます。 (a hrefhttps://github.com/joyent/node/blob/v0.11.14/src/node.js#L783>https://github.com/joyent/node/blob/v0.11.14/src/node.js#L783/a>)/p>h3>D/h3>p>ここで新たなモジュールとしてModuleのa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9>インスタンス/a>を作ります。(ここで渡されてるcode>parent/code>がcode>module.parent/code>として永久に保持される)/p>p>そしてそれをそのままパスをキーとしてキャッシュします。/p>p>この段階では別にパスからソースをa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB>コンパイル/a>したりはしてません。/p>p>とくにa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%B9%A5%C8%A5%E9%A5%AF%A5%BF>コンストラクタ/a>内にそういう処理はありません。/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>function/span> Module(id, span classsynStatement>parent/span>) span classsynIdentifier>{/span> span classsynIdentifier>this/span>.id id; span classsynIdentifier>this/span>.exports span classsynIdentifier>{}/span>; span classsynIdentifier>this/span>.span classsynStatement>parent/span> span classsynStatement>parent/span>; span classsynStatement>if/span> (span classsynStatement>parent/span> && span classsynStatement>parent/span>.children) span classsynIdentifier>{/span> span classsynStatement>parent/span>.children.push(span classsynIdentifier>this/span>); span classsynIdentifier>}/span> span classsynIdentifier>this/span>.filename span classsynStatement>null/span>; span classsynIdentifier>this/span>.loaded span classsynConstant>false/span>; span classsynIdentifier>this/span>.children span classsynIdentifier>/span>;span classsynIdentifier>}/span>/pre>h3>E/h3>p>ここでcode>Module.load/code>を利用してソースをa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB>コンパイル/a>し、code>module.exports/code>を返却してます。/p>p>この時読み込みに失敗したエラーはcatchはされないものの、その後のfinalyでcacheだけは綺麗に消されるので、ロード失敗時に変なキャッシュが残ることはないはずです。/p>p>次はソースをa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB>コンパイル/a>するところを追います。/p>h2>module.load/h2>pre classcode lang-javascript data-langjavascript data-unlink>Module.prototype.load span classsynIdentifier>function/span>(filename) span classsynIdentifier>{/span> span classsynComment>// 省略/span> span classsynComment>// A/span> span classsynIdentifier>var/span> extension path.extname(filename) || span classsynConstant>.js/span>; span classsynStatement>if/span> (!Module._extensionsspan classsynIdentifier>/span>extensionspan classsynIdentifier>/span>) extension span classsynConstant>.js/span>; span classsynComment>// B/span> Module._extensionsspan classsynIdentifier>/span>extensionspan classsynIdentifier>/span>(span classsynIdentifier>this/span>, filename); span classsynIdentifier>this/span>.loaded span classsynConstant>true/span>;span classsynIdentifier>}/span>;/pre>h3>A/h3>p>a classkeyword hrefhttp://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%BB%D2>拡張子/a>ごとのローダーを利用するため、どのローダーを利用するかの判別のためにファイルパスからa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%BB%D2>拡張子/a>を抜き出します。 (デフォルト .js)/p>p>ローダーがないようなa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%BB%D2>拡張子/a>の場合はとりあえず.js用のローダーで試すみたいです。/p>h3>B/h3>p>a classkeyword hrefhttp://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%BB%D2>拡張子/a>ごとのローダーによって読み込みを開始します。/p>p>code>Module.exteisonsextension/code>というのがローダーです。/p>p>通常我々が利用するのはcode>.js/code>とcode>.json/code>くらいでしょうか。 あと一応code>.node/code>というローダーもあるみたいです。/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynComment>// Native extension for .js/span>Module._extensionsspan classsynIdentifier>/span>span classsynConstant>.js/span>span classsynIdentifier>/span> span classsynIdentifier>function/span>(module, filename) span classsynIdentifier>{/span> span classsynIdentifier>var/span> content fs.readFileSync(filename, span classsynConstant>utf8/span>); module._compile(stripBOM(content), filename);span classsynIdentifier>}/span>;span classsynComment>// Native extension for .json/span>Module._extensionsspan classsynIdentifier>/span>span classsynConstant>.json/span>span classsynIdentifier>/span> span classsynIdentifier>function/span>(module, filename) span classsynIdentifier>{/span> span classsynIdentifier>var/span> content fs.readFileSync(filename, span classsynConstant>utf8/span>); span classsynStatement>try/span> span classsynIdentifier>{/span> module.exports JSON.parse(stripBOM(content)); span classsynIdentifier>}/span> span classsynStatement>catch/span> (err) span classsynIdentifier>{/span> err.message filename + span classsynConstant>: /span> + err.message; span classsynStatement>throw/span> err; span classsynIdentifier>}/span>span classsynIdentifier>}/span>;/pre>p>.a classkeyword hrefhttp://d.hatena.ne.jp/keyword/json>json/a>のほうは簡単ですね。/p>p>ファイルを同期的に読み出してcode>stripBOM/code>でa classkeyword hrefhttp://d.hatena.ne.jp/keyword/utf-8>utf-8/a>のBOM(a hrefhttp://www.wdic.org/w/WDIC/UTF-8#BOM>http://www.wdic.org/w/WDIC/UTF-8#BOM/a>)を取り除いたものをcode>JSON.parse/code>してオブジェクトにもどしてそれをcode>module.exports/code>にセットしています。/p>p>.a classkeyword hrefhttp://d.hatena.ne.jp/keyword/json>json/a>はこれでおしまいです。/p>p>.jsのほうはもうちょっと複雑なのでBOMを排除したファイルコンテンツを取得したあと、code>module._compile/code>に処理を移譲しています。/p>p>よくこのローダーはspan stylecolor: #ff0000>テストとかでrequireしたものをスタブに置き換えるために使われたり/span>します。/p>p>a hrefhttp://stackoverflow.com/questions/6997459/how-to-stub-require-expect-calls-to-the-root-function-of-a-module#answer-7037187>javascript - How to stub require() / expect calls to the "root" function of a module? - Stack Overflow/a>/p>p>ドキュメント上では廃止予定となってるけどコアコードに根深く存在してるので事実上これは廃止できませんみたいなこと書いてあるので複雑な感じですね。/p>p>でも、そういうことしたいとき、多分ほかの方法はa classkeyword hrefhttp://d.hatena.ne.jp/keyword/vm>vm/a>使ったりとかもっと荒々しい方法とかになると思います。/p>h2>module._compile/h2>p>a hrefhttps://github.com/joyent/node/blob/v0.11.14/lib/module.js#L378>https://github.com/joyent/node/blob/v0.11.14/lib/module.js#L378/a>/p>p>長かったけどこれで最後です。/p>pre classcode lang-javascript data-langjavascript data-unlink>Module.prototype._compile span classsynIdentifier>function/span>(content, filename) span classsynIdentifier>{/span> span classsynIdentifier>var/span> span classsynStatement>self/span> span classsynIdentifier>this/span>; span classsynComment>// A/span> span classsynComment>// remove shebang/span> content content.replace(span classsynConstant>/^\#\!.*//span>, span classsynConstant>/span>); span classsynComment>// B/span> span classsynIdentifier>function/span> require(path) span classsynIdentifier>{/span> span classsynStatement>return/span> span classsynStatement>self/span>.require(path); span classsynIdentifier>}/span> require.resolve span classsynIdentifier>function/span>(request) span classsynIdentifier>{/span> span classsynStatement>return/span> Module._resolveFilename(request, span classsynStatement>self/span>); span classsynIdentifier>}/span>; span classsynType>Object/span>.defineProperty(require, span classsynConstant>paths/span>, span classsynIdentifier>{/span> get: span classsynIdentifier>function/span>() span classsynIdentifier>{/span> span classsynStatement>throw/span> span classsynStatement>new/span> Error(span classsynConstant>require.paths is removed. Use /span> + span classsynConstant>node_modules folders, or the NODE_PATH /span> + span classsynConstant>environment variable instead./span>); span classsynIdentifier>}}/span>); require.main process.mainModule; span classsynComment>// Enable support to add extra extension types/span> require.extensions Module._extensions; require.registerExtension span classsynIdentifier>function/span>() span classsynIdentifier>{/span> span classsynStatement>throw/span> span classsynStatement>new/span> Error(span classsynConstant>require.registerExtension() removed. Use /span> + span classsynConstant>require.extensions instead./span>); span classsynIdentifier>}/span>; require.cache Module._cache; span classsynComment>// C/span> span classsynIdentifier>var/span> dirname path.dirname(filename); span classsynComment>// 省略/span> span classsynComment>// create wrapper function/span> span classsynComment>// D/span> span classsynIdentifier>var/span> wrapper Module.wrap(content); span classsynIdentifier>var/span> compiledWrapper runInThisContext(wrapper, span classsynIdentifier>{/span> filename: filename span classsynIdentifier>}/span>); span classsynComment>// 省略/span> span classsynComment>// E/span> span classsynIdentifier>var/span> args span classsynIdentifier>/span>span classsynStatement>self/span>.exports, require, span classsynStatement>self/span>, filename, dirnamespan classsynIdentifier>/span>; span classsynStatement>return/span> compiledWrapper.apply(span classsynStatement>self/span>.exports, args);span classsynIdentifier>}/span>;/pre>h3>A/h3>p>ソースからシェバン( #!/usr/bin/env node ←こういうの)があれば取り除きます/p>h3>B/h3>p>読み込まれるモジュールのローカル変数として使うcode>require/code>を定義します。/p>p>なかみは単純にcode>module.require/code>です。/p>p>ここまででみてきたcode>require/code>と同じものです(属するmoduleは呼び元と呼び先とで違うけど)/p>p>code>require/code>のもつa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9>メソッド/a>( a hrefhttp://nodejs.jp/nodejs.org_ja/api/globals#globals_require>http://nodejs.jp/nodejs.org_ja/api/globals#globals_require/a> )を定義していきます。/p>p>code>require.resolve/code>は中でcode>Module._resolveFilename/code>に処理を移譲してますね。/p>p>これはcode>module._load/code>の中でファイルパスを解決したa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9>メソッド/a>です。/p>p>なのでspan stylecolor: #ff0000>code>require.resolve/code>を使ってファイルパスを解決すればそのままモジュールのキャッシュキーが安全につくれたりします/span>。/p>p>あとはちらほら廃止になったa classkeyword hrefhttp://d.hatena.ne.jp/keyword/api>api/a>用の対応がみられますね。/p>h3>C/h3>p>この読み込まれるモジュールのディレクトリパスを取得しています。/p>p>これが読み込まれるモジュールのローカル変数として使うcode>__dirname/code>になります。/p>p>ちなみにcode>__filename/code>はさきほどModule._resolveFilenameによって解決されたパスをそのままつかいます。/p>h3>D/h3>p>ソースをラップします。/p>p>以前この部分だけ記事にしました( a hrefhttp://nazomikan.hateblo.jp/entry/2013/04/30/144154>Nodeのファイルスコープ - ぶれすとつーる/a> )/p>p>実行コード(文字列)を/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynConstant>(function (exports, require, module, __filename, __dirname) { /span> + source + span classsynConstant>/span>span classsynSpecial>\n/span>span classsynConstant>});/span>/pre>p>こんな感じでラップするものです。/p>p>こうすることで読み込まれるモジュールにスコープができ、あらかじめそこに存在するローカル変数を(引数にセットすることで)用意することができます。/p>p>そしてこうしてできたコード文字列をcode>runInThisContext/code>でa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB>コンパイル/a>します。/p>p>code>runInThisContext/code>はa classkeyword hrefhttp://d.hatena.ne.jp/keyword/vm>vm/a>モジュールのcode>vm.runInThisContext/code>と同じです。/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> runInThisContext require(span classsynConstant>vm/span>).runInThisContext;/pre>p>これは実行元のローカル変数とかにはアクセスできないけど同じglobalを共有形式のコード評価です。/p>p>第二引数で渡してるfilenameのオプションはa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%B9%A5%BF%A5%C3%A5%AF%A5%C8%A5%EC%A1%BC%A5%B9>スタックトレース/a>時の表示用の情報です。/p>p>これで code>function (exports, require, module, __filename, __dirname { source }/code> が得られました。/p>h3>E/h3>p>あとはそれぞれ引数( code>self.exports, require, self, filename, dirname/code> )をapplyでセットして実行しています。/p>p>code>self/code>は自身のcode>module/code>をさします。/p>p>code>module.exports/code>とcode>exports/code>が同じ参照のものだということがここからわかりますね。/p>p>しばしばモジュール内で/p>pre classcode lang-javascript data-langjavascript data-unlink>exports span classsynIdentifier>function/span> () span classsynIdentifier>{/span> ... span classsynIdentifier>}/span>/pre>p>が期待した動きをしないけどなんで??みたいな質問がwebに溢れてますがこれをみれば一目瞭然ですね。/p>p>span stylecolor: #ff0000>ただのローカル変数なんだから参照を切るような代入をしたらmodule.exportsに反映されなくなりますね、exportsにはなんのマジック的要素もありません。/span>/p>pre classcode lang-javascript data-langjavascript data-unlink>module.exports span classsynIdentifier>function/span> () span classsynIdentifier>{/span> ... span classsynIdentifier>}/span>/pre>p>を使いましょう。/p>p>長くなりましたが各モジュールのcode>require/code>の動きをおってみました。/p>p>途中横道にそれそうな処理は省略しましたがnative_moduleの解釈の仕方などもあるので見ると収穫があるかもしれません。/p> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741>time data-relative datetime2014-12-23T12:27:41Z title2014-12-23T12:27:41Z classupdated>2014-12-23 21:27/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_mediumbutton&utm_sourceblogs_entry_footer&utm_campaignsubscribe_blog> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741 data-hatena-star-titlerequireの仕組み data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2014/12/23/212741 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?textrequire%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2014%2F12%2F23%2F212741 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> div idgoogle_afc_user_container_3 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-4800 words-600 mode-markdown entry-even identry-8454420450077706830 data-keyword-campaign data-uuid8454420450077706830 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2014/12/22 relnofollow> time datetime2014-12-21T18:52:37Z title2014-12-21T18:52:37Z> span classdate-year>2014/span>span classhyphen>-/span>span classdate-month>12/span>span classhyphen>-/span>span classdate-day>22/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237 classentry-title-link bookmark>Argumentsと関数内の変数環境の関係/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/javascript classentry-category-link category-javascript>javascript/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/ECMAScript classentry-category-link category-ECMAScript>ECMAScript/a> /div> /header> div classentry-content hatenablog-entry> p>おはようございます。/p>p>この記事はa classkeyword hrefhttp://d.hatena.ne.jp/keyword/Javascript>Javascript/a> Advent Calender 2014の22日目の記事です。/p>p>iframe srchttp://hatenablog.com/embed?urlhttp%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2014%2Fjavascript titleJavaScript Advent Calendar 2014 - Qiita classembed-card embed-webcard scrollingno frameborder0 stylewidth: 100%; height: 155px; max-width: 500px; margin: 10px 0px;>a hrefhttp://qiita.com/advent-calendar/2014/javascript>JavaScript Advent Calendar 2014 - Qiita/a>/iframe>/p>p>a hrefhttp://qiita.com/advent-calendar/2014/javascript>JavaScript Advent Calendar 2014 - Qiita/a>/p>p>domenicのツイートをストーキングしてたら、とある話を拾った。/p>blockquote classtwitter-tweet langja>p>I forgot about this until yesterday: `var f function(a) { a 'a classkeyword hrefhttp://d.hatena.ne.jp/keyword/lol>lol/a>'; console.log(arguments) }; f(42);`/p>— Ryan Florence (@ryanflorence) a hrefhttps://twitter.com/ryanflorence/status/546328507106607104>2014, 12月 20/a>/blockquote>script async src//platform.twitter.com/widgets.js charsetutf-8>/script>p>議題のコードはこれ/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> f span classsynIdentifier>function/span>(a) span classsynIdentifier>{/span> a span classsynConstant>lol/span>; console.log(span classsynIdentifier>arguments/span>);span classsynIdentifier>}/span>;f(42);span classsynComment>// 実行結果/span>span classsynComment>// "lol"/span>/pre>p>Argumentsオブジェクトを普通のオブジェクトと思っているとここで違和感を感じる/p>p>もう一個例を見てみる/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> f span classsynIdentifier>function/span> (a) span classsynIdentifier>{/span> a span classsynConstant>lol/span>; console.log(b);span classsynIdentifier>}/span>span classsynIdentifier>var/span> b span classsynIdentifier>{/span>d: 10span classsynIdentifier>}/span>;f(b.d);span classsynComment>// 実行結果/span>span classsynComment>// Object {d: 10}/span>/pre>p>違和感を感じた人は、多分この結果と同じように引数aはarguments0の値をコピー(今回はプリミティブ値なので)してるように考えるので、aを変更したところでarguments0自身には影響がないはずなのでは?って思ってしまうんだと思う。/p>p>さらに/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> f span classsynIdentifier>function/span>(a) span classsynIdentifier>{/span> span classsynIdentifier>arguments/span>0span classsynIdentifier>/span> span classsynConstant>lol/span>; console.log(a)span classsynIdentifier>}/span>;f(42);span classsynComment>// 実行結果/span>span classsynComment>// lol/span>/pre>p>これもArgumentsにとても詳しいおじさん以外きっと違和感を感じると思う。/p>p>これらの挙動を見るにArgumentsは普通のオブジェクトではない。/p>p>結構いろいろ変なやつっぽい。/p>p>仕様を見てみるとその内部的な動きがわかった。/p>p>Argumentsは内部的にCreateMappedArgumentsObject (ES5まではCreateArgumentsObject)の呼出しによって生成される。/p>ul>li>ES6-draftul>li>a hrefhttp://people.mozilla.org/~jorendorff/es6-draft.html#sec-createmappedargumentsobject>ECMAScript Language Specification ECMA-262 6th Edition – DRAFT/a>/li>/ul>/li>li>ES5ul>li>a hrefhttp://www.ecma-international.org/ecma-262/5.1/#sec-10.6>http://www.ecma-international.org/ecma-262/5.1/#sec-10.6/a>/li>/ul>/li>/ul>p>ざっくりいうと、Argumentsオブジェクトに引数でセットされた値を引数インデックスをキーとしてセットしている。/p>p>そしてミソなのは、非strictモード化のときに、内部的にi>map/i>というオブジェクトを作成し、その中に引数にセットされた値を引数indexをキーとしてセットし、Argumentsから参照(code>Get/code>)された時にi>map/i>の該当キーの値を返却する/p>p>(strictモード化では単純にArgumentsにセットされた値を返却するだけ)。/p>p>このi>map/i>に対する引数のセットの仕方が特殊で以下のように記述されてる/p>blockquote>ol>li>p>Let g be i>MakeArgGetter(name, env)/i>./p>/li>li>p>Let p be i>MakeArgSetter(name, env)/i>./p>/li>li>p>Call the code>DefineOwnProperty/code> internal method of map passing ToString(index) and the PropertyDescriptor{code>Set/code>: p, code>Get/code>: g,code>Enumerable/code>: false, code>Configurable/code>: true} as arguments./p>/li>/ol>/blockquote>p>単純にcode>Value/code>にセットするのではなくMakeArgGetter/Setterにi>env/i>と共に渡した結果をcode>Getter/code>、code>Setter/code>にセットしてプロパティ定義をしている。/p>p>※ ここでいうi>name/i>は引数名 function fn(a, b){} だとしたら aやbという引数名にあたる/p>p>※ ここでいうi>env/i>はこのargumentsの存在する関数対する変数環境にあたる(所謂 変数オブジェクト)/p>p>このMakeArgGetter/Setterがこの一見変な挙動を生み出してる。/p>p>MakeArgGetterは以下のように記述されている/p>blockquote>p>9.4.4.7.1 MakeArgGetter ( name, env) Abstract Operation/p>p>The abstract operation MakeArgGetter called with String i>name/i> and environment record i>env/i> creates a built-in function object that span stylecolor: #ff0000>when executed returns the value bound for name in env./span>/p>/blockquote>p>適当な約: MakeArgGetterは変数環境i>env/i>のi>name/i>の値を返却するような関数を作る/p>p>es5では簡単にこんな風にかかれてる/p>blockquote>ol>li>Let body be the result of concatenating the Stringsspan stylecolor: #ff0000> return , name, and ;/span>./li>li>Return the result of creating a function object as described in 13.2 using no FormalParameterList, body for FunctionBody, span stylecolor: #ff0000>i>env/i> as Scope/span>, and true for Strict./li>/ol>/blockquote>p>scopeにi>env/i>をセットするってかいてあるので擬似的に表現するとこんな感じになると思う。/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>function/span> A(a, b) span classsynIdentifier>{/span> span classsynComment>// arguments0のGetは function () { return a; } /span> span classsynComment>// arguments1のGetは function () { return b; } /span>span classsynIdentifier>}/span>/pre>p>es6-draftの方ではMakeArgGetterの返す関数について/p>blockquote>ol>li>Return the result of calling the GetBindingValue concrete method of env with arguments name and false./li>/ol>/blockquote>p>となってるので挙動として同様の結果になるはず(GetBindingValueは変数環境から与えられたnameの値を返却する内部処理)/p>p>こう考えれば 最初の例(↓)/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> f span classsynIdentifier>function/span>(a) span classsynIdentifier>{/span> a span classsynConstant>lol/span>; console.log(span classsynIdentifier>arguments/span>);span classsynIdentifier>}/span>;f(42);span classsynComment>// 実行結果/span>span classsynComment>// "lol"/span>/pre>p>のように変数aがa classkeyword hrefhttp://d.hatena.ne.jp/keyword/lol>lol/a>に書き変わればarguments0の値もgetterを通して変数aが返却されてるだけなので同様の結果を返すということがわかる。/p>p>またMakeArgSetterは以下のように記述されてる/p>blockquote>p>The abstract operation MakeArgSetter called with String i>name/i> and environment record i>env/i> creates a built-in function object that span stylecolor: #ff0000>when executed sets the i>value/i> bound for i>name/i> in i>env/i>/span>./p>/blockquote>p>適当な約: MakeArgSetterは変数環境i>env/i>のi>name/i>にi>value/i>をセットする関数を作る/p>p>es5では簡単にこんな風にかかれてる/p>blockquote>ol>li>p>Let param be the String name concatenated with the String _arg./p>/li>li>p>Let body be the String span stylecolor: #ff0000>code><name> <param>;/code> /span>with name> replaced by the value of name and code><param>/code> replaced by the value of param./p>/li>li>p>Return the result of creating a function object as described in 13.2 using a List containing the single String i>param/i> as FormalParameterList, body for FunctionBody, span stylecolor: #ff0000>i>env/i> as Scope/span>, and true for Strict./p>/li>/ol>/blockquote>p>scopeにi>env/i>をセットするってかいてあるので擬似的に表現するとこんな感じになると思う。/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>function/span> A(a, b) span classsynIdentifier>{/span> span classsynComment>// arguments0のSetは function (_arga) { return a _arga; }/span> span classsynComment>// arguments1のSetは function (_argb) { return b _argb; } /span>span classsynIdentifier>}/span>/pre>p>es6-draftの方では、MakeArgSetterの返す関数について/p>blockquote>ol>li>Return the result of calling the SetMutableBinding concrete method of i>env/i> with arguments i>name/i>, i>value/i>, and false./li>/ol>/blockquote>p>となってるのでこれもまた挙動的には同じだと思う(SetMutableBindingは変数環境に存在するnameの値内部にvalueをセットする内部処理)/p>p>こう考えれば 結構前の例(↓)/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> f span classsynIdentifier>function/span>(a) span classsynIdentifier>{/span> span classsynIdentifier>arguments/span>0span classsynIdentifier>/span> span classsynConstant>lol/span>; console.log(a)span classsynIdentifier>}/span>;f(42);span classsynComment>// 実行結果/span>span classsynComment>// lol/span>/pre>p>のようにarguments0がa classkeyword hrefhttp://d.hatena.ne.jp/keyword/lol>lol/a>に書き変わればsetterを通して変数環境aにa classkeyword hrefhttp://d.hatena.ne.jp/keyword/lol>lol/a>がセットされるので変数aも同様に値がかわってしまうことがわかる/p>p>とまぁ挙動に関してはここまででわかったけど辛いのuse strictつけて回避したいですね。(callee, callerもアクセス拒否されるようになるし)/p>p>あとes6ではcode>...args/code>(argumentsの単純な配列版)があるのでそれを使えばこの現象に遭遇することもないんでしょうね/p>p>おわりです。/p> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237>time data-relative datetime2014-12-21T18:52:37Z title2014-12-21T18:52:37Z classupdated>2014-12-22 03:52/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_mediumbutton&utm_sourceblogs_entry_footer&utm_campaignsubscribe_blog> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237 data-hatena-star-titleArgumentsと関数内の変数環境の関係 data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2014/12/22/035237 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?textArguments%E3%81%A8%E9%96%A2%E6%95%B0%E5%86%85%E3%81%AE%E5%A4%89%E6%95%B0%E7%92%B0%E5%A2%83%E3%81%AE%E9%96%A2%E4%BF%82+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2014%2F12%2F22%2F035237 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> script> (valve window.valve || ).push(function(v) { v.displayDFPSlot(google_afc_user_container_4); }); /script> div idgoogle_afc_user_container_4 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-2800 words-400 mode-markdown entry-odd identry-8454420450077637911 data-keyword-campaign data-uuid8454420450077637911 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2014/12/21 relnofollow> time datetime2014-12-20T23:47:52Z title2014-12-20T23:47:52Z> span classdate-year>2014/span>span classhyphen>-/span>span classdate-month>12/span>span classhyphen>-/span>span classdate-day>21/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752 classentry-title-link bookmark>サーバ側でd3を使って作ったsvgを画像に変換して返す/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/Node classentry-category-link category-Node>Node/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/d3 classentry-category-link category-d3>d3/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/Canvas classentry-category-link category-Canvas>Canvas/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/svg classentry-category-link category-svg>svg/a> /div> /header> div classentry-content hatenablog-entry> p>おはようございます、この記事はd3.js Advent Calendar 2014の21日目の記事です。/p>p>iframe srchttp://hatenablog.com/embed?urlhttp%3A%2F%2Fqiita.com%2Fadvent-calendar%2F2014%2Fd3 titled3.js Advent Calendar 2014 - Qiita classembed-card embed-webcard scrollingno frameborder0 stylewidth: 100%; height: 155px; max-width: 500px; margin: 10px 0px;>a hrefhttp://qiita.com/advent-calendar/2014/d3>d3.js Advent Calendar 2014 - Qiita/a>/iframe>/p>p>a hrefhttp://qiita.com/advent-calendar/2014/d3>d3.js Advent Calendar 2014 - Qiita/a>/p>p>つい先日からd3を使い始めました。/p>p>d3のpackage.a classkeyword hrefhttp://d.hatena.ne.jp/keyword/json>json/a>読んでたらnode側から使う場合はjsdomを使ってるっぽいのみつけた。ドキュメントにも書いてあったけどサーバサイドでも普通にjsdom使ってdom操作的なやつできるらしい。/p>p>ならサーバサイドでデータを元にa classkeyword hrefhttp://d.hatena.ne.jp/keyword/svg>svg/a>組み立てて、それをnode-a classkeyword hrefhttp://d.hatena.ne.jp/keyword/canvas>canvas/a>に転写してa classkeyword hrefhttp://d.hatena.ne.jp/keyword/png>png/a>なりに変換してstreamでレスポンスにながせるよねって思ったのでやってみた。/p>h2>必要なモジュールのインストール/h2>p>a classkeyword hrefhttp://d.hatena.ne.jp/keyword/svg>svg/a>をnode-a classkeyword hrefhttp://d.hatena.ne.jp/keyword/canvas>canvas/a>に転写するのfabricが多分一番簡単なのでこれをいれる/p>p>でもその前にそれが依存してるnode-a classkeyword hrefhttp://d.hatena.ne.jp/keyword/canvas>canvas/a>のためにcairoいれる必要がある。/p>p>多分一番辛い作業だけどこの辺がんばってください/p>p>iframe srchttp://hatenablog.com/embed?urlhttps%3A%2F%2Fgithub.com%2FAutomattic%2Fnode-canvas%2Fwiki titleAutomattic/node-canvas classembed-card embed-webcard scrollingno frameborder0 stylewidth: 100%; height: 155px; max-width: 500px; margin: 10px 0px;>a hrefhttps://github.com/Automattic/node-canvas/wiki>Automattic/node-canvas/a>/iframe>/p>p>a hrefhttps://github.com/Automattic/node-canvas/wiki>Home · Automattic/node-canvas Wiki · GitHub/a>/p>p>このcairoがんばる作業が終わったらあとは普通に必要なモジュールをnpmからもってきます/p>pre classcode lang-sh data-langsh data-unlink>npm span classsynStatement>install/span> fabricnpm span classsynStatement>install/span> d3/pre>h2>アプリケーションの作成/h2>p>まずはサーバサイドでa classkeyword hrefhttp://d.hatena.ne.jp/keyword/svg>svg/a>を組み立てます/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> d3 require(span classsynConstant>d3/span>) , body d3.select(span classsynConstant>body/span>) , svg ;span classsynComment>// 赤い丸を作る例/span>body .append(span classsynConstant>svg/span>) .attr(span classsynIdentifier>{/span>width: 300, height: 300span classsynIdentifier>}/span>) .append(span classsynConstant>circle/span>) .attr(span classsynIdentifier>{/span>cx: 150, cy: 150, r: 100, fill: span classsynConstant>#ff0000/span>span classsynIdentifier>}/span>);svg body.node().innerHTMLconsole.log(svg);span classsynComment>// <svg width"300" height"300">/span>span classsynComment>// <circle cx"150" cy"150" r"100" fill"#ff0000"></circle>/span>span classsynComment>// </svg>/span>/pre>p>これをfabricを使ってa classkeyword hrefhttp://d.hatena.ne.jp/keyword/canvas>canvas/a>に転写する/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynComment>// svg文字列から画像情報を読みこむ/span>fabric.loadSVGFromString(svg, span classsynIdentifier>function/span> (objects, options) span classsynIdentifier>{/span> span classsynIdentifier>var/span> canvas, obj, stream; canvas fabric.createCanvasForNode(300, 300); obj fabric.util.groupSVGElements(objects, options); canvas.add(obj).renderAll();span classsynIdentifier>}/span>);/pre>p>あとはサーバ書いてレスポンスに垂れ流す完成版/p>pre classcode lang-javascript data-langjavascript data-unlink>span classsynIdentifier>var/span> http require(span classsynConstant>http/span>) , d3 require(span classsynConstant>d3/span>) , fabric require(span classsynConstant>fabric/span>).fabric ;http.createServer(span classsynIdentifier>function/span>(req, res) span classsynIdentifier>{/span> span classsynIdentifier>var/span> canvas fabric.createCanvasForNode(300, 300) , body d3.select(span classsynConstant>body/span>) , svg ; body .append(span classsynConstant>svg/span>) .attr(span classsynIdentifier>{/span>width: 300, height: 300span classsynIdentifier>}/span>) .append(span classsynConstant>circle/span>) .attr(span classsynIdentifier>{/span>cx: 150, cy: 150, r: 100, fill: span classsynConstant>#ff0000/span>span classsynIdentifier>}/span>); svg body.node().innerHTML; fabric.loadSVGFromString(svg, span classsynIdentifier>function/span> (objects, options) span classsynIdentifier>{/span> span classsynIdentifier>var/span> obj, stream; obj fabric.util.groupSVGElements(objects, options); canvas.add(obj).renderAll(); stream canvas.createPNGStream(); stream.on(span classsynConstant>data/span>, span classsynIdentifier>function/span>(chunk) span classsynIdentifier>{/span> res.write(chunk); span classsynIdentifier>}/span>); stream.on(span classsynConstant>end/span>, span classsynIdentifier>function/span>() span classsynIdentifier>{/span> res.end(); span classsynIdentifier>}/span>); span classsynIdentifier>}/span>);span classsynIdentifier>}/span>).listen(3000);/pre>p>サーバ起動して該当ページ ( a hrefhttp://localhost:3000/>http://localhost:3000//a> )にアクセスすると日の丸ができてるはず。/p>h3>表示/h3>p>span itemscope itemtypehttp://schema.org/Photograph>img srchttp://cdn-ak.f.st-hatena.com/images/fotolife/n/nazomikan/20141221/20141221075206.png altf:id:nazomikan:20141221075206p:plain titlef:id:nazomikan:20141221075206p:plain classhatena-fotolife itempropimage>/span>/p>h2>それっぽいやつ/h2>pre classcode lang-javascript data-langjavascript data-unlink>span classsynComment>// .../span> span classsynComment>// それっぽいデータ/span> color d3.scale.category20(); data span classsynIdentifier>/span>5, 10, 2, 20, 5, 8, 13, 25, 26, 29, 22, 6span classsynIdentifier>/span>; body .append(span classsynConstant>"svg"/span>) .attr(span classsynIdentifier>{/span>width: width, height: heightspan classsynIdentifier>}/span>) .append(span classsynConstant>g/span>) .selectAll(span classsynConstant>rect/span>) .data(data).enter() .append(span classsynConstant>rect/span>).attr(span classsynConstant>x/span>, span classsynIdentifier>function/span> (d,i) span classsynIdentifier>{/span> span classsynStatement>return/span> (i * 25) + 5 span classsynIdentifier>}/span>) .attr(span classsynConstant>y/span>, span classsynIdentifier>function/span> (d,i) span classsynIdentifier>{/span> span classsynStatement>return/span> height - (d * 10) span classsynIdentifier>}/span>) .attr(span classsynConstant>width/span>, 20).attr(span classsynConstant>height/span>, span classsynIdentifier>function/span> (d, i) span classsynIdentifier>{/span> span classsynStatement>return/span> d * 10 span classsynIdentifier>}/span>) .attr(span classsynConstant>fill/span>, span classsynIdentifier>function/span> (d, i) span classsynIdentifier>{/span> span classsynStatement>return/span> color(i); span classsynIdentifier>}/span>); svg body.node().innerHTML;fabric.loadSVGFromString(svg, span classsynIdentifier>function/span> (objects, options) span classsynIdentifier>{/span> span classsynComment>// .../span>/pre>h3>表示/h3>p>span itemscope itemtypehttp://schema.org/Photograph>img srchttp://cdn-ak.f.st-hatena.com/images/fotolife/n/nazomikan/20141221/20141221084021.png altf:id:nazomikan:20141221084021p:plain titlef:id:nazomikan:20141221084021p:plain classhatena-fotolife itempropimage>/span>/p>p>それっぽいですね!></p> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752>time data-relative datetime2014-12-20T23:47:52Z title2014-12-20T23:47:52Z classupdated>2014-12-21 08:47/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_sourceblogs_entry_footer&utm_mediumbutton&utm_campaignsubscribe_blog> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752 data-hatena-star-titleサーバ側でd3を使って作ったsvgを画像に変換して返す data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2014/12/21/084752 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?text%E3%82%B5%E3%83%BC%E3%83%90%E5%81%B4%E3%81%A7d3%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E4%BD%9C%E3%81%A3%E3%81%9Fsvg%E3%82%92%E7%94%BB%E5%83%8F%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2014%2F12%2F21%2F084752 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> script> (valve window.valve || ).push(function(v) { v.displayDFPSlot(google_afc_user_container_5); }); /script> div idgoogle_afc_user_container_5 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-400 words-100 mode-markdown entry-even identry-12921228815731895097 data-keyword-campaign data-uuid12921228815731895097 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2014/09/02 relnofollow> time datetime2014-09-02T14:21:39Z title2014-09-02T14:21:39Z> span classdate-year>2014/span>span classhyphen>-/span>span classdate-month>09/span>span classhyphen>-/span>span classdate-day>02/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2014/09/02/232139 classentry-title-link bookmark>YUIの開発終了とYUICompressor/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/javascript classentry-category-link category-javascript>javascript/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/css classentry-category-link category-css>css/a> /div> /header> div classentry-content hatenablog-entry> p>a hrefhttp://yahooeng.tumblr.com/post/96098168666/important-announcement-regarding-yui>Important Announcement Regarding YUI/a>/p>p>この記事でa classkeyword hrefhttp://d.hatena.ne.jp/keyword/YUI>YUI/a>の積極的なメンテナンスがもうなされないよみたいな話を聞いてa classkeyword hrefhttp://d.hatena.ne.jp/keyword/YUI>YUI/a> Compressorもメンテされなくなるのかなーなんて思って聞いてみたんだけどa classkeyword hrefhttp://d.hatena.ne.jp/keyword/YUI>YUI/a> Compressorの管理は2012年の時点でownershipがかわってたみたいで、もうずいぶんと前からYAHOO主体の管理ではなかったみたい/p>p>今のメインメンテナはJoey Smithって方がしてるみたいで今後もメンテナンスやめる予定はないとのこと/p>p>まだ今すぐというわけではないけど時期バージョンv2.4.9も、現在抱えてる問題を解決できたら出すみたい/p>p>a hrefhttps://github.com/yui/yuicompressor/issues/158>Will you release v2.4.9? · Issue #158 · yui/yuicompressor · GitHub/a>/p> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2014/09/02/232139>time data-relative datetime2014-09-02T14:21:39Z title2014-09-02T14:21:39Z classupdated>2014-09-02 23:21/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_sourceblogs_entry_footer&utm_mediumbutton&utm_campaignsubscribe_blog> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2014/09/02/232139 data-hatena-star-titleYUIの開発終了とYUICompressor data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2014/09/02/232139 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2014/09/02/232139 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2014/09/02/232139>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?textYUI%E3%81%AE%E9%96%8B%E7%99%BA%E7%B5%82%E4%BA%86%E3%81%A8YUICompressor+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2014%2F09%2F02%2F232139 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> script> (valve window.valve || ).push(function(v) { v.displayDFPSlot(google_afc_user_container_6); }); /script> div idgoogle_afc_user_container_6 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> article classentry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-2400 words-200 mode-markdown entry-odd identry-12921228815725534958 data-keyword-campaign data-uuid12921228815725534958 data-publication-typeentry> div classentry-inner> header classentry-header> div classdate entry-date first> a hrefhttps://nazomikan.hateblo.jp/archive/2014/06/05 relnofollow> time datetime2014-06-04T18:15:48Z title2014-06-04T18:15:48Z> span classdate-year>2014/span>span classhyphen>-/span>span classdate-month>06/span>span classhyphen>-/span>span classdate-day>05/span> /time> /a> /div> h1 classentry-title> a hrefhttps://nazomikan.hateblo.jp/entry/2014/06/05/031548 classentry-title-link bookmark>socket.ioで特定ユーザーにemitしたい時/a>/h1> div classentry-categories categories> a hrefhttps://nazomikan.hateblo.jp/archive/category/javascript classentry-category-link category-javascript>javascript/a> a hrefhttps://nazomikan.hateblo.jp/archive/category/websocket classentry-category-link category-websocket>websocket/a> /div> /header> div classentry-content hatenablog-entry> p>最近socket.ioがメジャーバージョンになって少しかわって/p>p>今まで/p>pre classcode lang-javascript data-langjavascript data-unlink>io.sockets.socket(id).json.emit(span classsynConstant>msg/span>, send_msg);/pre>p>みたいな感じでかけてたのですがsockets (namespace)がsocketa classkeyword hrefhttp://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9>メソッド/a>を持たなくなってて、「あれ特定ユーザ探す方法なくね」って思ってたんだけどドキュメントよんでたら/p>blockquote>p>Each Socket in Socket.IO is identified by a random, unguessable, unique identifier Socket#id. > For your convenience, each socket automatically joins a room identified by this id./p>p>This makes it easy to broadcast messages to other sockets:/p>/blockquote>p>Socket.IOの各ソケットはランダム、推測できない、ユニークな識別子のソケット#IDで識別されます。あなたの便宜のために、各ソケットは自動的にこのIDで識別される部屋に参加します。これにより、簡単に他のソケットにメッセージを配信することができる/p>p>ってあるの見つけた。/p>p>各socketは自動的にIDで識別される部屋に参加するってあるっていってるのでそのルームに対してemitするのってどうしたらいいんだろっておもったらその辺うまくやってくれるsocket#to見つけた。/p>p>(メジャーバージョン以前からこのa classkeyword hrefhttp://d.hatena.ne.jp/keyword/API>API/a>はあったんだけど)/p>pre classcode lang-javascript data-langjavascript data-unlink>Socket.prototype.to Socket.prototype.span classsynStatement>in/span> span classsynIdentifier>function/span>(name)span classsynIdentifier>{/span> span classsynIdentifier>this/span>._rooms span classsynIdentifier>this/span>._rooms || span classsynIdentifier>/span>; span classsynStatement>if/span> (!~span classsynIdentifier>this/span>._rooms.indexOf(name)) span classsynIdentifier>this/span>._rooms.push(name); span classsynStatement>return/span> span classsynIdentifier>this/span>;span classsynIdentifier>}/span>;/pre>p>渡されたname(sokecet#id)を見て次の通信のためのroomを指定できる感じになってるそして実際に送信するsocket#emitみると/p>pre classcode lang-javascript data-langjavascript data-unlink>Socket.prototype.emit span classsynIdentifier>function/span>(ev)span classsynIdentifier>{/span> span classsynStatement>if/span> (~exports.events.indexOf(ev)) span classsynIdentifier>{/span> emit.apply(span classsynIdentifier>this/span>, span classsynIdentifier>arguments/span>); span classsynIdentifier>}/span> span classsynStatement>else/span> span classsynIdentifier>{/span> span classsynIdentifier>var/span> args span classsynType>Array/span>.prototype.slice.call(span classsynIdentifier>arguments/span>); span classsynIdentifier>var/span> packet span classsynIdentifier>{}/span>; packet.type hasBin(args) ? parser.BINARY_EVENT : parser.EVENT; packet.data args; span classsynComment>// access last argument to see if its an ACK callback/span> span classsynStatement>if/span> (span classsynConstant>function/span> span classsynStatement>typeof/span> argsspan classsynIdentifier>/span>args.length - 1span classsynIdentifier>/span>) span classsynIdentifier>{/span> span classsynStatement>if/span> (span classsynIdentifier>this/span>._rooms || (span classsynIdentifier>this/span>.flags && span classsynIdentifier>this/span>.flags.broadcast)) span classsynIdentifier>{/span> span classsynStatement>throw/span> span classsynStatement>new/span> Error(span classsynConstant>Callbacks are not supported when broadcasting/span>); span classsynIdentifier>}/span> debug(span classsynConstant>emitting packet with ack id %d/span>, span classsynIdentifier>this/span>.nsp.ids); span classsynIdentifier>this/span>.acksspan classsynIdentifier>this/span>.nsp.idsspan classsynIdentifier>/span> args.pop(); packet.id span classsynIdentifier>this/span>.nsp.ids++; span classsynIdentifier>}/span> span classsynStatement>if/span> (span classsynIdentifier>this/span>._rooms || (span classsynIdentifier>this/span>.flags && span classsynIdentifier>this/span>.flags.broadcast)) span classsynIdentifier>{/span> span classsynIdentifier>this/span>.adapter.broadcast(packet, span classsynIdentifier>{/span> except: span classsynIdentifier>this/span>.idspan classsynIdentifier>/span>, rooms: span classsynIdentifier>this/span>._rooms, flags: span classsynIdentifier>this/span>.flags span classsynIdentifier>}/span>); span classsynIdentifier>}/span> span classsynStatement>else/span> span classsynIdentifier>{/span> span classsynComment>// dispatch packet/span> span classsynIdentifier>this/span>.packet(packet); span classsynIdentifier>}/span> span classsynComment>// reset flags/span> span classsynStatement>delete/span> span classsynIdentifier>this/span>._rooms; span classsynStatement>delete/span> span classsynIdentifier>this/span>.flags; span classsynIdentifier>}/span> span classsynStatement>return/span> span classsynIdentifier>this/span>;span classsynIdentifier>}/span>;/pre>p>となってて基本的に対象となるroomに対してイベントを配信してるっぽい。/p>p>※送信後roomは都度消去される/p>p>ということなんで最初かいてたこれ/p>pre classcode lang-javascript data-langjavascript data-unlink>io.sockets.socket(id).json.emit(span classsynConstant>msg/span>, send_msg);/pre>p>これをroomを使ったイベント配信に書き換えると/p>pre classcode lang-javascript data-langjavascript data-unlink>socket.to(id).json.emit(span classsynConstant>msg/span>, send_msg);/pre>p>みたいにできてよしなに動いた。/p>p>Namespaceにも同様の実装の#toあったり、Serverもdefault namespace code>.of(/)/code> のtoにaliasはってあるのでこんな感じにサーバーから直接呼ぶ事もできる/p>pre classcode lang-javascript data-langjavascript data-unlink>io.to(id).json.emit(span classsynConstant>msg/span>, send_msg);/pre> /div> footer classentry-footer> div classentry-tags-wrapper> div classentry-tags> /div>/div> p classentry-footer-section track-inview-by-gtm data-gtm-track-json{"area": "finish_reading"}> span classauthor vcard>span classfn data-load-nickname1 data-user-namenazomikan >nazomikan/span>/span> span classentry-footer-time>a hrefhttps://nazomikan.hateblo.jp/entry/2014/06/05/031548>time data-relative datetime2014-06-04T18:15:48Z title2014-06-04T18:15:48Z classupdated>2014-06-05 03:15/time>/a>/span> span class entry-footer-subscribe data-test-blog-controlls-subscribe> a hrefhttps://blog.hatena.ne.jp/nazomikan/nazomikan.hateblo.jp/subscribe?utm_campaignsubscribe_blog&utm_mediumbutton&utm_sourceblogs_entry_footer> 読者になる /a> /span> /p> div classhatena-star-container data-hatena-star-container data-hatena-star-urlhttps://nazomikan.hateblo.jp/entry/2014/06/05/031548 data-hatena-star-titlesocket.ioで特定ユーザーにemitしたい時 data-hatena-star-variantprofile-icon data-hatena-star-profile-url-templatehttps://blog.hatena.ne.jp/{username}/ >/div> div classsocial-buttons> div classsocial-button-item> a hrefhttps://b.hatena.ne.jp/entry/s/nazomikan.hateblo.jp/entry/2014/06/05/031548 classhatena-bookmark-button data-hatena-bookmark-urlhttps://nazomikan.hateblo.jp/entry/2014/06/05/031548 data-hatena-bookmark-layoutvertical-balloon data-hatena-bookmark-langja titleこの記事をはてなブックマークに追加>img srchttps://b.st-hatena.com/images/entry-button/button-only.gif altこの記事をはてなブックマークに追加 width20 height20 styleborder: none; />/a> /div> div classsocial-button-item> div classfb-share-button data-layoutbox_count data-hrefhttps://nazomikan.hateblo.jp/entry/2014/06/05/031548>/div> /div> div classsocial-button-item> a classentry-share-button entry-share-button-twitter test-share-button-twitter hrefhttps://x.com/intent/tweet?textsocket.io%E3%81%A7%E7%89%B9%E5%AE%9A%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%ABemit%E3%81%97%E3%81%9F%E3%81%84%E6%99%82+-+%E3%81%B6%E3%82%8C%E3%81%99%E3%81%A8%E3%81%A4%E3%83%BC%E3%82%8B&urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2Fentry%2F2014%2F06%2F05%2F031548 titleX(Twitter)で投稿する >/a> /div> /div> div classgoogle-afc-image test-google-rectangle-ads> script> (valve window.valve || ).push(function(v) { v.displayDFPSlot(google_afc_user_container_7); }); /script> div idgoogle_afc_user_container_7 classgoogle-afc-user-container google_afc_blocklink2_5 google_afc_boder data-test-unit/4374287/blog_user_2nd>/div> a hrefhttp://blog.hatena.ne.jp/guide/pro classopen-pro-modal data-guide-pro-modal-ad-urlhttps://hatena.blog/guide/pro/modal/ad>広告を非表示にする/a> /div> div classcustomized-footer> /div> div classcomment-box js-comment-box> ul classcomment js-comment> li classread-more-comments styledisplay: none;>a>もっと読む/a>/li> /ul> a classleave-comment-title js-leave-comment-title>コメントを書く/a> /div> /footer> /div>/article> !-- rakuten_ad_target_end --> !-- google_ad_section_end --> div classpager autopagerize_insert_before> span classpager-next> a hrefhttps://nazomikan.hateblo.jp/?page1401905748 relnext>次のページ/a> /span> /div> /div> /div> aside idbox1> div idbox1-inner> /div>/aside> /div>!-- #wrapper --> aside idbox2> div idbox2-inner> div classhatena-module hatena-module-profile> div classhatena-module-title> プロフィール /div> div classhatena-module-body> a hrefhttps://nazomikan.hateblo.jp/about classprofile-icon-link> img srchttps://cdn.profile-image.st-hatena.com/users/nazomikan/profile.png?1348997035 altid:nazomikan classprofile-icon /> /a> span classid> a hrefhttps://nazomikan.hateblo.jp/about classhatena-id-link>span data-load-nickname1 data-user-namenazomikan>id:nazomikan/span>/a> /span> div classprofile-description> p>だいたいjavascript/p> /div> div classhatena-follow-button-box btn-subscribe js-hatena-follow-button-box > a href# classhatena-follow-button js-hatena-follow-button> span classsubscribing> span classforeground>読者です/span> span classbackground>読者をやめる/span> /span> span classunsubscribing data-track-nameprofile-widget-subscribe-button data-track-once> span classforeground>読者になる/span> span classbackground>読者になる/span> /span> /a> div classsubscription-count-box js-subscription-count-box> i>/i> u>/u> span classsubscription-count js-subscription-count> /span> /div>/div> div classprofile-about> a hrefhttps://nazomikan.hateblo.jp/about>このブログについて/a> /div> /div>/div> div classhatena-module hatena-module-search-box> div classhatena-module-title> 検索 /div> div classhatena-module-body> form classsearch-form rolesearch actionhttps://nazomikan.hateblo.jp/search methodget> input typetext nameq classsearch-module-input value placeholder記事を検索 required> input typesubmit value検索 classsearch-module-button />/form> /div>/div> div classhatena-module hatena-module-links> div classhatena-module-title> リンク /div> div classhatena-module-body> ul classhatena-urllist> li> a hrefhttp://hatenablog.com/>はてなブログ/a> /li> li> a hrefhttp://blog.hatena.ne.jp/guide?via200109>ブログをはじめる(無料)/a> /li> li> a hrefhttp://staff.hatenablog.com/>お知らせ/a> /li> /ul> /div>/div> div classhatena-module hatena-module-recent-entries > div classhatena-module-title> a hrefhttps://nazomikan.hateblo.jp/archive> 最新記事 /a> /div> div classhatena-module-body> ul classrecent-entries hatena-urllist > li classurllist-item recent-entries-item> div classurllist-item-inner recent-entries-item-inner> a hrefhttps://nazomikan.hateblo.jp/entry/2016/11/14/225509 classurllist-title-link recent-entries-title-link urllist-title recent-entries-title>CSS&FP WG/a> /div> /li> li classurllist-item recent-entries-item> div classurllist-item-inner recent-entries-item-inner> a hrefhttps://nazomikan.hateblo.jp/entry/2015/05/17/000755 classurllist-title-link recent-entries-title-link urllist-title recent-entries-title> exotic objectがhost objectの呼び名が変わったものという風潮/a> /div> /li> li classurllist-item recent-entries-item> div classurllist-item-inner recent-entries-item-inner> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/23/212741 classurllist-title-link recent-entries-title-link urllist-title recent-entries-title>requireの仕組み/a> /div> /li> li classurllist-item recent-entries-item> div classurllist-item-inner recent-entries-item-inner> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/22/035237 classurllist-title-link recent-entries-title-link urllist-title recent-entries-title>Argumentsと関数内の変数環境の関係/a> /div> /li> li classurllist-item recent-entries-item> div classurllist-item-inner recent-entries-item-inner> a hrefhttps://nazomikan.hateblo.jp/entry/2014/12/21/084752 classurllist-title-link recent-entries-title-link urllist-title recent-entries-title>サーバ側でd3を使って作ったsvgを画像に変換して返す/a> /div> /li> /ul> /div>/div> div classhatena-module hatena-module-archive data-archive-typedefault data-archive-urlhttps://nazomikan.hateblo.jp/archive> div classhatena-module-title> a hrefhttps://nazomikan.hateblo.jp/archive>月別アーカイブ/a> /div> div classhatena-module-body> ul classhatena-urllist> li classarchive-module-year archive-module-year-hidden data-year2016> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2016 classarchive-module-year-title archive-module-year-2016> 2016 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2016/11 classarchive-module-month-title archive-module-month-2016-11> 2016 / 11 /a> /li> /ul> /li> li classarchive-module-year archive-module-year-hidden data-year2015> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2015 classarchive-module-year-title archive-module-year-2015> 2015 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2015/05 classarchive-module-month-title archive-module-month-2015-5> 2015 / 5 /a> /li> /ul> /li> li classarchive-module-year archive-module-year-hidden data-year2014> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2014 classarchive-module-year-title archive-module-year-2014> 2014 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/12 classarchive-module-month-title archive-module-month-2014-12> 2014 / 12 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/09 classarchive-module-month-title archive-module-month-2014-9> 2014 / 9 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/06 classarchive-module-month-title archive-module-month-2014-6> 2014 / 6 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/04 classarchive-module-month-title archive-module-month-2014-4> 2014 / 4 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/03 classarchive-module-month-title archive-module-month-2014-3> 2014 / 3 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/02 classarchive-module-month-title archive-module-month-2014-2> 2014 / 2 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2014/01 classarchive-module-month-title archive-module-month-2014-1> 2014 / 1 /a> /li> /ul> /li> li classarchive-module-year archive-module-year-hidden data-year2013> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2013 classarchive-module-year-title archive-module-year-2013> 2013 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2013/12 classarchive-module-month-title archive-module-month-2013-12> 2013 / 12 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2013/06 classarchive-module-month-title archive-module-month-2013-6> 2013 / 6 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2013/05 classarchive-module-month-title archive-module-month-2013-5> 2013 / 5 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2013/04 classarchive-module-month-title archive-module-month-2013-4> 2013 / 4 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2013/03 classarchive-module-month-title archive-module-month-2013-3> 2013 / 3 /a> /li> /ul> /li> li classarchive-module-year archive-module-year-hidden data-year2012> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2012 classarchive-module-year-title archive-module-year-2012> 2012 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2012/12 classarchive-module-month-title archive-module-month-2012-12> 2012 / 12 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2012/10 classarchive-module-month-title archive-module-month-2012-10> 2012 / 10 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2012/04 classarchive-module-month-title archive-module-month-2012-4> 2012 / 4 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2012/02 classarchive-module-month-title archive-module-month-2012-2> 2012 / 2 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2012/01 classarchive-module-month-title archive-module-month-2012-1> 2012 / 1 /a> /li> /ul> /li> li classarchive-module-year archive-module-year-hidden data-year2011> div classarchive-module-button> span classarchive-module-hide-button>▼/span> span classarchive-module-show-button>▶/span> /div> a hrefhttps://nazomikan.hateblo.jp/archive/2011 classarchive-module-year-title archive-module-year-2011> 2011 /a> ul classarchive-module-months> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2011/12 classarchive-module-month-title archive-module-month-2011-12> 2011 / 12 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2011/09 classarchive-module-month-title archive-module-month-2011-9> 2011 / 9 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2011/03 classarchive-module-month-title archive-module-month-2011-3> 2011 / 3 /a> /li> li classarchive-module-month> a hrefhttps://nazomikan.hateblo.jp/archive/2011/02 classarchive-module-month-title archive-module-month-2011-2> 2011 / 2 /a> /li> /ul> /li> /ul> /div>/div> div classhatena-module hatena-module-circles> div classhatena-module-title> 参加グループ /div> div classhatena-module-body> ul classhatena-urllist circle-urllist> li title個人の日記 data-circle-id12921228815715899733 data-circle-mtime1764550908> a hrefhttps://hatena.blog/g/12921228815715899733>img classcircle-image srchttps://cdn.image.st-hatena.com/image/square/6a2fff45eb94e2ce13280e6a9ebac8a8c320fb8e/backendimagemagick;height96;version1;width96/https%3A%2F%2Fcdn.blog.st-hatena.com%2Fimages%2Fcircle%2Fcircle-icon.png alt個人の日記 title個人の日記>/a> a hrefhttps://hatena.blog/g/12921228815715899733>個人の日記/a>/li> /ul> /div>/div> /div>/aside> /div>/div> /div> /div> footer idfooter data-brandhatenablog> div idfooter-inner> address classfooter-address> a hrefhttps://nazomikan.hateblo.jp/> img srchttps://cdn.image.st-hatena.com/image/square/2d93421ee8e17e776a21e2ba5cf8156cb1037f63/backendimagemagick;height128;version1;width128/https%3A%2F%2Fcdn.user.blog.st-hatena.com%2Fcustom_blog_icon%2F7401858%2F151424748738795 width16 height16 altぶれすとつーる/> span classfooter-address-name>ぶれすとつーる/span> /a> /address> p classservices> Powered by a hrefhttps://hatena.blog/>Hatena Blog/a> | a hrefhttps://blog.hatena.ne.jp/-/abuse_report?target_urlhttps%3A%2F%2Fnazomikan.hateblo.jp%2F classreport-abuse-link test-report-abuse-link target_blank>ブログを報告する/a> /p> /div>/footer> script async srchttps://s.hatena.ne.jp/js/widget/star.js>/script> script> if (typeof window.Hatena undefined) { window.Hatena {}; } if (!Hatena.hasOwnProperty(Star)) { Hatena.Star { VERSION: 2, }; } /script> div idfb-root>/div>script>(function(d, s, id) { var js, fjs d.getElementsByTagName(s)0; if (d.getElementById(id)) return; js d.createElement(s); js.id id; js.src //connect.facebook.net/ja_JP/sdk.js#xfbml1&appId719729204785177&versionv17.0; fjs.parentNode.insertBefore(js, fjs);}(document, script, facebook-jssdk));/script> div classquote-box> div classtooltip-quote tooltip-quote-stock> i classblogicon-quote title引用をストック>/i> /div> div classtooltip-quote tooltip-quote-tweet js-tooltip-quote-tweet> a classjs-tweet-quote target_blank data-track-namequote-tweet data-track-once> img srchttps://cdn.blog.st-hatena.com/images/admin/quote/quote-x-icon.svg?versiona9c7d634032ae4419eb72f1520ec87 title引用して投稿する > /a> /div>/div>div classquote-stock-panel idquote-stock-message-box styleposition: absolute; z-index: 3000> div classmessage-box idquote-stock-succeeded-message styledisplay: none> p>引用をストックしました/p> button classbtn btn-primary idquote-stock-show-editor-button data-track-namecuration-quote-edit-button>ストック一覧を見る/button> button classbtn quote-stock-close-message-button>閉じる/button> /div> div classmessage-box idquote-login-required-message styledisplay: none> p>引用するにはまずログインしてください/p> button classbtn btn-primary idquote-login-button>ログイン/button> button classbtn quote-stock-close-message-button>閉じる/button> /div> div classerror-box idquote-stock-failed-message styledisplay: none> p>引用をストックできませんでした。再度お試しください/p> button classbtn quote-stock-close-message-button>閉じる/button> /div> div classerror-box idunstockable-quote-message-box styledisplay: none; position: absolute; z-index: 3000;> p>限定公開記事のため引用できません。/p> /div>/div>script typex-underscore-template idjs-requote-button-template> div classrequote-button js-requote-button> button classrequote-button-btn tipsy-top title引用する>i classblogicon-quote>/i>/button> /div>/script> div idhidden-subscribe-button styledisplay: none;> div classhatena-follow-button-box btn-subscribe js-hatena-follow-button-box > a href# classhatena-follow-button js-hatena-follow-button> span classsubscribing> span classforeground>読者です/span> span classbackground>読者をやめる/span> /span> span classunsubscribing data-track-nameprofile-widget-subscribe-button data-track-once> span classforeground>読者になる/span> span classbackground>読者になる/span> /span> /a> div classsubscription-count-box js-subscription-count-box> i>/i> u>/u> span classsubscription-count js-subscription-count> /span> /div>/div> /div> script async srchttps://platform.twitter.com/widgets.js charsetutf-8>/script>script srchttps://b.st-hatena.com/js/bookmark_button.js charsetutf-8 asyncasync>/script>script typetext/javascript srchttps://cdn.blog.st-hatena.com/js/external/jquery.min.js?v1.12.4&versiona9c7d634032ae4419eb72f1520ec87>/script>script srchttps://cdn.blog.st-hatena.com/js/texts-ja.js?versiona9c7d634032ae4419eb72f1520ec87>/script> script idvendors-js data-envproduction srchttps://cdn.blog.st-hatena.com/js/vendors.js?versiona9c7d634032ae4419eb72f1520ec87 crossoriginanonymous>/script>script idhatenablog-js data-envproduction srchttps://cdn.blog.st-hatena.com/js/hatenablog.js?versiona9c7d634032ae4419eb72f1520ec87 crossoriginanonymous data-page-idindex>/script> script>Hatena.Diary.GlobalHeader.init()/script> script idvalve-dmp data-serviceblog srchttps://cdn.pool.st-hatena.com/valve/dmp.js data-test-iddmpjs async>/script> /body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]