草庐IT

javascript - 难以手动走原型(prototype)链

coder 2025-01-01 原文

我想尝试手动遍历几个对象的原型(prototype)链,看看我在这个过程中找到了什么。但是,我卡在了我尝试的第一个上。这是代码:

function MyObject() { }
var x = new MyObject();
console.log('--------------------------------------------');
console.log('x.constructor.name: ' + x.constructor.name);
console.log('x.constructor.prototype.constructor.name: ' + x.constructor.prototype.constructor.name);
console.log(x.constructor.prototype === Function.prototype ? 'Good guess.' : 'No, you are wrong.');
console.log(x.constructor === MyObject ? 'Good guess.' : 'No, you are wrong.');
console.log('--------------------------------------------');

上述代码会在 Google Chrome 的开发者工具控制台中产生以下输出:

--------------------------------------------
x.constructor.name: MyObject
x.constructor.prototype.constructor.name: MyObject
No, you are wrong.
Good guess.
--------------------------------------------

x 的构造函数是 MyObject 函数是有道理的,因为 x 是使用 MyObject 上的 new 关键字实例化的(这遵循构造函数的定义)。因此,我理解了第一行输出(注意:我开始从零开始计算输出行数)。然而,第二行让我感到困惑。我想知道 MyObject 的原型(prototype)是什么。显然,它不是函数类型的对象,如输出的第 3 行所示,这告诉我我错了。第四行输出只是加强了第一行的输出。

更笼统地说,我假设遍历对象原型(prototype)链的正确方法是从所讨论的对象到它的构造函数,然后从构造函数到构造函数的原型(prototype),假设这是最后一个引用不为空。我假设应该重复这个两步过程(包括转到构造函数,然后转到构造函数的原型(prototype)),直到达到从构造函数到原型(prototype)的空引用,从而表示原型(prototype)链的结尾。不过,这似乎不起作用,因为将此算法应用于上述场景只会导致循环引用。

总结起来,我有两个问题:

  1. 为什么 x.constructor === x.constructor.prototype.constructor(或者,换句话说,为什么循环引用),以及 x.constructor.prototype 是一个什么样的对象,无论如何(或者,换句话说,话说,它是如何实例化的/它从哪里来的)?
  2. 如何修正上述算法才能正确遍历对象 x 的原型(prototype)链?

编辑

我在 StackOverflow 上遇到了类似的问题 here ,但它没有明确询问遍历原型(prototype)链的正确方法。它确实指出了循环引用,但是......

最佳答案

在 Javascript 术语中,对象 a 的“原型(prototype)”是指 a 从中继承属性的对象。访问它的基于标准的方法是使用 Object.getPrototypeOf:

var protoOfA = Object.getPrototypeOf(a);

还有一些旧方法,非标准但受某些浏览器支持:

var protoOfA = a.__proto__;

但是如果你有一个函数 F,F.prototype 不会引用 F 从中继承任何东西的对象。相反,它指的是 F 创建的实例 继承自的对象:

function F() {};
a = new F();
console.log(Object.getPrototypeOf(a) === F.prototype); // true

当您定义一个函数时,会创建一个对象作为该函数创建的实例的原型(prototype),并且这个新对象存储在该函数的 prototype 属性中。

--

函数在很多方面表现得像对象(例如,它们可以具有属性)但它们与其他对象并不完全相同:

console.log(typeof a); // "object"
console.log(typeof F); // "function"

他们的“原型(prototype)”定义不明确(示例在 Chrome 中运行)(这显然是 Chrome-specific behavior )

console.log(Object.getPrototypeOf(F)); // "function Empty() {}"
console.log(Empty);                    // ReferenceError: Empty is not defined

--

constructor 属性很奇怪。 The interpreter doesn't care about it . MDN says, confusingly :

Returns a reference to the Object function that created the instance's prototype.

此外,您可以更改对象上 constructor 的值,但这对对象是什么或它的行为方式没有影响 - 它只是描述性的。

--

所以,回答你的问题:

Why is x.constructor === x.constructor.prototype.constructor

没有充分的理由。这是浏览器收敛的任意行为。

what kind of an object is x.constructor.prototype, anyway

在这个例子中,t 是x 的原型(prototype),与Object.getPrototypeOf(x) 相同。但一般来说,您不能依赖 x.constructor 或任何派生自它的东西,因为它是任意的。

How can the above algorithm be corrected in order to correctly walk the prototype chain for object x?

for (var p = x ; p != null ; p = Object.getPrototypeOf(p)) {
  // do something with p
}

关于javascript - 难以手动走原型(prototype)链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29975939/

有关javascript - 难以手动走原型(prototype)链的更多相关文章

  1. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  2. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  3. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  4. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  5. jquery - 在 Rails 中从原型(prototype)切换到 jquery,助手呢? - 2

    我目前从prototype切换到jquery主要是为了支持简单的ajax文件上传。我使用:https://github.com/indirect/jquery-rails95%的javascript代码是由railshelper编写的,例如:-remote_function-render:updatedo|page|-page.replace_html'id',:partial=>'content'-page['form']['name']=something-page.visual_effect:highlight,'head_success'...我知道我必须为Jquery重写5%

  6. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

    出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

  7. ruby - Watir-Webdriver 是否支持点击目标为 javascript 的链接? - 2

    我是Ruby和Watir-Webdriver的新手。我有一套用VBScript编写的站点自动化程序,我想将其转换为Ruby/Watir,因为我现在必须支持Firefox。我发现我真的很喜欢Ruby,而且我正在研究Watir,但我已经花了一周时间试图让Webdriver显示我的登录屏幕。该站点以带有“我同意”区域的“警告屏幕”开头。用户点击我同意并显示登录屏幕。我需要单击该区域以显示登录屏幕(这是同一页面,实际上是一个表单,只是隐藏了)。我整天都在用VBScript这样做:objExplorer.Document.GetElementsByTagName("area")(0).click

  8. ruby-on-rails - Foreman无法启动Nginx,但我可以手动启动。为什么? - 2

    我目前正在运行Foreman在暂存(Ubuntu)上,一旦我开始工作,就会切换到使用upstart。我的Procfile.staging看起来像这样:nginx:sudoservicenginxstartunicorn:bundleexecunicorn-c./config/unicorn.rbredis:bundleexecredis-serversidekiq:bundleexecsidekiq-v-C./config/sidekiq.yml我可以使用以下方法成功启动nginx:$sudoservicenginxstart然而,当我运行$foremanstart时,当其他三个进程成

  9. 网页设计期末作业,基于HTML+CSS+JavaScript超酷超炫的汽车类企业网站(6页) - 2

    🎉精彩专栏推荐💭文末获取联系✍️作者简介:一个热爱把逻辑思维转变为代码的技术博主💂作者主页:【主页——🚀获取更多优质源码】🎓web前端期末大作业:【📚毕设项目精品实战案例(1000套)】🧡程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作(110套)】🌎超炫酷的Echarts大屏可视化源码:【🔰Echarts大屏展示大数据平台可视化(150套)】🔖HTML+CSS+JS实例代码:【🗂️5000套HTML+CSS+JS实例代码(炫酷代码)继续更新中…】🎁免费且实用的WEB前端学习指南:【📂web前端零基础到高级学习视频教程120G干货分享】🥇关于作者:💬历任研发工程师,技术组长,教学总监;

  10. ruby-on-rails - 在页面的最底部包含 javascript 文件 - 2

    我有一个Rails应用程序。还有一个javascript(javascript1.js)文件必须包含在每个View的最底部。我把它放在/assets/javascripts文件夹中。Application.js包含以下代码//=requirejquery//=requirejquery_ujs//=someotherfiles//=require_directory.即使Application.js中不包含javascript1.js,它也会自动包含,不是吗?那么我怎样才能做我想做的事呢? 最佳答案 单独定义、包含和执行您的java

随机推荐