-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjs_prototype.html
1 lines (1 loc) · 11 KB
/
js_prototype.html
1
<!doctype html><html lang="zh-CN" class="night"><head><meta charset="utf-8"><meta content="width=device-width,initial-scale=1,maximum-scale=4,user-scalable=0" name="viewport"><title>Ede's Blog</title><meta name="description" content="Try to be a qualified programmer"><meta property="og:type" content="website"><meta property="og:description" content="Try to be a qualified programmer"><meta property="og:title" content="Ede's Blog"><meta property="og:site_name" content="Ede's Blog"><meta property="og:url" content="https://ede.ink"><meta property="og:image" content="https://edeity.oss-cn-shenzhen.aliyuncs.com/public/edeity_o.png"><link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"><link rel="mainfest" href="/mainfest.json"><link rel="stylesheet" href="/public/css/common.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_707055_4b9og9sc5lx.css"><script>!function(){var e=-1!==window.location.search.indexOf("theme=night")||"night"===window.localStorage.getItem("edeity-theme_theme"),t=-1!==window.location.search.indexOf("theme=light")||"light"===window.localStorage.getItem("edeity-theme_theme");(new Date).getHours();var n=document.querySelector("html");e?n.classList.add("night"):t?n.classList.remove("night"):n.classList.add("night")}(),document.addEventListener("DOMContentLoaded",function(){null!==document.querySelector("ol.toc")&&(document.querySelector("#nav-bar").style.cssText="display: block")})</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-M3J9QSEE2Z"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-M3J9QSEE2Z")</script><meta name="generator" content="Hexo 5.0.0"></head><body><div class="loading"></div><div id="switch" data-switch="{"toc":true,"use_pwa":false}"></div><header class="fullscreen"><div class="toolbar"><i class="iconfont icon-menu"></i></div><h1><a href="/">Ede's Blog</a></h1><div class="head-link"><a class="btn waves" href="/"><span><i class="iconfont icon-home">Home </i></span></a><a class="btn waves" href="/about/index.html"><span><i class="iconfont icon-me">About </i></span></a><a class="btn waves" target="_blank" rel="noopener" href="https://github.com/edeink"><span><i class="iconfont icon-github">Github</i></span></a></div></header><div class="some-link"><a class="btn" id="light-or-not"><i class="iconfont icon-light"></i> </a><a style="display:none" class="btn" id="up-to-top"><i class="iconfont icon-up"></i></a></div><div id="nav-bar" style="display:none"><div class="toc"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E5%8E%9F%E5%9E%8B%E9%93%BE%E7%9A%84%E6%80%9D%E8%80%83"><span class="toc-number">1.</span> <span class="toc-text">关于原型链的思考</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%A3%E6%9E%90"><span class="toc-number">2.</span> <span class="toc-text">解析</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%A7%E8%A1%8C%E5%89%8D%E7%9A%84%E5%8E%9F%E5%9E%8B%E7%8A%B6%E6%80%81"><span class="toc-number">2.1.</span> <span class="toc-text">执行前的原型状态</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#new%E5%85%B3%E9%94%AE%E5%AD%97%E6%89%80%E8%B5%B7%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-number">2.2.</span> <span class="toc-text">new关键字所起的作用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%A7%E8%A1%8C%E5%89%8D%E5%90%8E%E7%9A%84%E5%8E%9F%E5%9E%8B%E9%93%BE%E5%8F%98%E5%8C%96"><span class="toc-number">2.3.</span> <span class="toc-text">执行前后的原型链变化</span></a></li></ol></li></ol></div></div><main id="content-main" class="section"><div class="list-item"><h1 class="post-title"><a id="理解Function和Object的原型关系" class="article-link" href="">理解Function和Object的原型关系</a></h1><div class="post-meta"><time class="meta published">Nov 9, 2015</time></div><div class="article"><div class="post-excerpt markdown-body"><p>源于某道js笔试题</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">//题目</span></span><br><span class="line"><span class="keyword">var</span> foo = {}</span><br><span class="line"><span class="keyword">var</span> F = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{}</span><br><span class="line"><span class="keyword">var</span> f = <span class="keyword">new</span> F()</span><br><span class="line"><span class="built_in">Object</span>.prototype.a = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{}</span><br><span class="line"><span class="built_in">Function</span>.prototype.b = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">//每次调用以下一个方法,哪些方法会报错</span></span><br><span class="line">foo.a()</span><br><span class="line">foo.b()</span><br><span class="line">F.a()</span><br><span class="line">F.b()</span><br><span class="line">f.a()</span><br><span class="line">f.b()</span><br></pre></td></tr></table></figure><p>答案:</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// foo.a(), F.a(), F.b(), f.a()调用成功</span></span><br><span class="line"><span class="comment">// foo.b(), F.b()调用失败</span></span><br><span class="line">foo.a() <span class="comment">//=> </span></span><br><span class="line">foo.b() <span class="comment">//=> TypeError: foo.b is not a function</span></span><br><span class="line">F.a() <span class="comment">//=></span></span><br><span class="line">F.b() <span class="comment">//=></span></span><br><span class="line">f.a() <span class="comment">//=></span></span><br><span class="line">f.b() <span class="comment">//=> TypeError: f.b is not a function</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="关于原型链的思考"><a href="#关于原型链的思考" class="headerlink" title="关于原型链的思考"></a>关于原型链的思考</h2><p>JS中,一个 <strong>变量</strong> 或 <strong>方法</strong> 的搜索是基于原型链的,如:<code>a.b()</code>,其伪代码:</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 假设a自能调用自身方法,a.b()类似于</span></span><br><span class="line"><span class="keyword">while</span>(a !== <span class="literal">null</span>) {</span><br><span class="line"> a.hasOwnProperty(b) ? a.b() : a = a.__proto__;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>为此,有句调侃javascript的话</p><blockquote><p>万物皆源于无(null)</p></blockquote><h2 id="解析"><a href="#解析" class="headerlink" title="解析"></a>解析</h2><p>要理解这道题目,最基本的思路在于:<strong>弄懂代码执行后,原型链的状态</strong></p><p>关键点又有两点</p><ol><li><strong>执行前</strong>的原型链状态</li><li><strong>new</strong>关键字的作用</li></ol><h3 id="执行前的原型状态"><a href="#执行前的原型状态" class="headerlink" title="执行前的原型状态"></a>执行前的原型状态</h3><p>es规范:请参考下面代码</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="built_in">Object</span>.__proto__ === <span class="built_in">Function</span>.prototype; <span class="comment">//=>true</span></span><br><span class="line"><span class="built_in">Object</span>.__proto__ === <span class="built_in">Function</span>.__proto__; <span class="comment">//=>true</span></span><br><span class="line"><span class="built_in">Function</span>.__proto__.__proto__ === <span class="built_in">Object</span>.prototype; <span class="comment">//=>true</span></span><br><span class="line"><span class="built_in">Function</span>.__proto__.__proto__.__proto__ === <span class="literal">null</span>; <span class="comment">//=>true</span></span><br></pre></td></tr></table></figure><h3 id="new关键字所起的作用"><a href="#new关键字所起的作用" class="headerlink" title="new关键字所起的作用"></a>new关键字所起的作用</h3><ul><li><p>一般地:</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> A()</span><br><span class="line"></span><br><span class="line"><span class="comment">//类似于</span></span><br><span class="line"><span class="keyword">var</span> a = {}</span><br><span class="line">a.__proto__ = A.prototype</span><br><span class="line">A.prototype.call(a) <span class="comment">//该句并不影响原型关系,可暂时忽略</span></span><br></pre></td></tr></table></figure></li><li><p>对于<code>new Function</code>,则存在一点不同</p><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> f = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{} <span class="comment">//或var f = new Function()</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">//类似于 </span></span><br><span class="line"><span class="keyword">var</span> f = {}</span><br><span class="line">f.__proto__ = <span class="built_in">Function</span>.prototype</span><br><span class="line">f.prototype = {} <span class="comment">// 独有</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.call(f)</span><br></pre></td></tr></table></figure></li></ul><h3 id="执行前后的原型链变化"><a href="#执行前后的原型链变化" class="headerlink" title="执行前后的原型链变化"></a>执行前后的原型链变化</h3><ul><li>执行前(图1)<br><img src="https://edeity.oss-cn-shenzhen.aliyuncs.com/2015/closure-before.jpg" alt="执行前"></li><li>执行后(图2)<br><img src="https://edeity.oss-cn-shenzhen.aliyuncs.com/2015/closure-before.jpg" alt="执行后"></li></ul><p>由图,可以很轻易得出</p><ul><li><code>foo.a()</code>会被调用成功</li><li><code>foo.b()</code>会报错</li></ul></div></div></div><div class="more section"><div class="pre"><a class="article-link" href="/learn_react_by_code_a_mou.html"><i class="iconfont icon-right"></i> <span>React初探:写一个“mou”</span></a></div><div class="next"><a class="article-link" href="/use_ali_cloud.html">阿里云搭建wordpress记 <i class="iconfont icon-right"></i></a></div></div></main></body><footer class="section fullscreen"><div class="footer-desc">Edeink © 2015-2022 · Powered by Hexo</div></footer><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="/public/js/init.js"></script></html>