是否有一种与环境无关的方法来检测Javascript主机对象? [英] Is there an environment-agnostic way to detect Javascript Host Objects?

查看:111
本文介绍了是否有一种与环境无关的方法来检测Javascript主机对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Javascript stacktrace库。库需要检测程序员创建的特定对象或函数,还是作为环境的一部分(包括内置对象)。主机对象由于其不可预测的行为而变得有点问题,所以我采用环境无关的方式来确定Javascript中的特定对象是否是宿主对象(参见 ECMAScript 3 - 4.3.8)。但是,区分主机对象与本机对象和原始值对于其他项目中的程序员很有用,特别是在无浏览器的环境中,所以我想关注它,而不是主机对象在我的库中导致的问题或区分程序员 - 创建对象。

I'm writing a Javascript stacktrace library. The library needs to detect wether a particular object or function was created by the programmer or was there as part of the environment (including built-in objects). Host objects are becoming a bit problematic due to their unpredictable behaviour, so I'm after an environment-agnostic way to determine if a particular object in Javascript is a host object (see ECMAScript 3 - 4.3.8). However, distinguishing host objects from native objects and primitive values is useful for programmers in other projects, particularly in browser-less environments, so I'd like to focus on that, rather than the problems host objects cause in my library or on distinguishing programmer-created objects.

到目前为止,我只能提出依赖于运行javascript代码的环境的解决方案。例如:

So far I've only been able to come up with solutions that depend on the environment running javascript code. For example:

// IE Only: does not implement valueOf() in Host Objects
var isHost = (typeof obj === 'object' && typeof obj.valueOf === 'undefined');

// Firefox Only: Host objects have own constructor
var isHost = (obj.constructor && obj.hasOwnProperty('constructor'));

我注意到jQuery自己的 isPlainObject()方法也依赖于环境,而且逻辑相当复杂。

I noticed that jQuery's own isPlainObject() method is also dependent on environment, and that the logic is rather convoluted.

也许这是因为具有主机对象的野兽的性质(因为它们的行为是由环境定义的),但我想进一步挖掘看看如果这是可能的,并且想知道是否有人之前遇到过这个特定的问题并准备好了解决方案。

Perhaps this is because thats the nature of the beast with host objects (since their behaviour is defined by the environment), but I would like to dig a bit further to see if this is possible and was wondering if somebody has run across this particular problem before and has a solution ready.

所以。有人知道一个简单的独立于平台的解决方案来测试主机对象吗?如果它在无浏览器的环境中运行,例如Node或Rhino,那就更好了。

So. Does anybody know a simple platform-independent solution to test for Host Objects? And if it runs in a browser-less environment such as Node or Rhino all the better for it.

可能的方法(可能不起作用):

Possible approaches (that may not work):


  • 测试主机对象的特性似乎是一个失败的原因,因为它们的行为没有规范,但测试对象是否是ES3规范的一部分可能是一种可能性。

  • 我尝试过使用 Object.prototype.toString(),因为它的定义非常具体,但结果是不确定的,因为某些环境(即IE)选择为本机和主机对象返回相同的值。

  • 可以通过检查最终构造函数对象实际上是一个 instanceof函数

  • Testing for characteristics of host objects seems like a lost cause, given that there is no specification for their behaviour, however testing whether the object is part of the ES3 specification may be a possibility.
  • I have tried using Object.prototype.toString() given that its defined quite specifically, but the results are inconclusive as some environments (namely IE) choose to return the same value for native and host objects.
  • It may be possible to do this by checking whether the ultimate constructor of an object through the prototype chain really is an instanceof Function.

推荐答案

当您查看主机对象的定义时 - 主机环境提供的对象,用于完成ECMAScript的执行环境。 - 很明显,没有简单的方法可以确定对象是主机还是本机。

When you look at the definition of host object — "object supplied by the host environment to complete the execution environment of ECMAScript." — it becomes pretty clear that there's no simple way to determine if an object is host or native.

与本机对象不同,主机对象以特定于实现的方式定义内部属性(例如[[Prototype]],[[Class]]等)。那是因为规范允许他们这样做。但是,主机对象没有必须要求以特定于实现的方式实现内部行为;这是一种可能类型的要求。所以我们不能依赖于此。这些对象可能会或可能不会怪异。没有办法说出来。

Unlike native objects, host objects define internal properties (such as [[Prototype]], [[Class]], etc.) in implementation-specific way. That's because specification allows them to do this. However, there's no "MUST" requirement for host objects to implement internal behavior in implementation-specific way; it's a "MAY" type of requirement. So we can't rely on this. These objects may or may not act "weird". There's no way to tell.

过去几乎没有尝试过检测宿主对象,但所有这些都明显依赖于某些环境的观察(MSHTML DOM是一个他们) - 记住宿主对象没有任何独特的模式/特征来识别。 Peter Michaux 记录了大部分推论(看看功能测试主机对象部分)。臭名昭着的 typeof ... ==unknown来自MSHTML DOM及其基于ActiveX的主机对象。请注意,Peter主要在浏览器脚本的上下文中讨论主机对象,并将检查缩小为这是一个主机方法吗?,这是一个主机集合对象等。

There have been few attempts to detect host objects in the past, but all of them obviously rely on observations of certain environments (MSHTML DOM being one of them) — remember that host objects don't have any kind of unique pattern/trait to identify by. Peter Michaux documented most of the inferences here (take a look at "Feature Testing a Host Object" section). The infamous typeof ... == "unknown" comes from MSHTML DOM and its ActiveX -based host objects. Note that Peter talks about host objects mainly in context of browser scripting, and he narrows the checks down to "is this a host method?", "is this a host collection object", etc.

在某些环境中,主机对象不会从 Object.prototype 继承(使其易于检查),或者某些抛出错误的属性(例如IE中某些接口对象上的原型),甚至在访问时自己抛出错误。

In some environments host objects don't inherit from Object.prototype (making it easy to check against), or have certain properties that throw errors (e.g. "prototype" on some "interface" objects in IE), or even throw errors themselves on access.

看起来你可能只是检查对象是否是规范中定义的对象之一,如果不是,则将其视为主机。但这并不会真正有用;它只会为你提供不是内置的对象。其中一些非标准对象仍然可以是原生的(这意味着它们将实现规范中描述的通常语义)。

It might seem like you could just check if an object is one of those defined in specification, and if not, deem it as host. But that won't really help; it would only give you objects that aren't built-in. Some of these non-standard objects could still be native (meaning that they would implement usual semantics as described in specification).

你最好的选择是测试对于您的应用/脚本的特定行为,主机对象可能对您很敏感。这始终是最安全的方式。你打算从对象上访问某些东西吗?从对象中删除内容?添加对象的东西?测试它。看看它是否有效。如果没有 - 你可能正在处理宿主对象。

Your best bet would be to test for particular behavior of your app/script, that host objects may be sensitive to. This is always the safest way. Are you planning to access something off of an object? Delete something from object? Add something to object? Test for it. See if it works. If it doesn't — you're likely dealing with host object.

这篇关于是否有一种与环境无关的方法来检测Javascript主机对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆