覆盖自定义对象的本机javascript函数名安全吗?

覆盖自定义对象的本机javascript函数名安全吗?,javascript,native-methods,Javascript,Native Methods,创建自定义对象时,为其提供覆盖本机js函数的方法(在我当前的例子中是“读取”、“写入”和“保存”)安全吗 所讨论的对象永远不必写入DOM(或者使用它将丢失的函数);这些方法名称非常理想,所以我很好奇,然后惊讶地发现很难找到一个明确的答案。下面的例子。谢谢 /** * Ticket class * @param category * @param issuedBy * @param reissuable If true, lock cannot be overridden by the s

创建自定义对象时,为其提供覆盖本机js函数的方法(在我当前的例子中是“读取”、“写入”和“保存”)安全吗

所讨论的对象永远不必写入DOM(或者使用它将丢失的函数);这些方法名称非常理想,所以我很好奇,然后惊讶地发现很难找到一个明确的答案。下面的例子。谢谢

/**
 * Ticket class
 * @param category
 * @param issuedBy
 * @param reissuable If true, lock cannot be overridden by the same method that locked it
 * @returns {Ticket}
 * @constructor
 */
Ticket = function (category, issuedBy, reissuable) {
    //properties
    this.id = Date.now().toString();
    this.category = category;
    this.resolved = false;
    this.issuingMethod = issuedBy;
    this.reissuable = reissuable === true;
    this.data = {};

    //methods
    this.resolve = function () { return this.resolved = true;};
    this.read = function (dataPath) { // find dataPath in this.data }
    this.write = function (dataPath, value) { // add value to dataPath of this.data}

    return this;
};

在提供的代码示例中,您没有重写任何本机方法。但是,如果不小心,您可能会重写从
Object.prototype
继承的本机方法

function MyObject() {}

MyObject.prototype.hasOwnProperty = function () { return true; };

new MyObject().hasOwnProperty('test'); //true
显然,这会产生误导,在这种情况下,我会选择另一个在您的域中具有类似含义的函数名,而不是覆盖本机
Object.prototype.hasOwnProperty
函数


在另一个答案中,有人说,在不使用
new
关键字的情况下调用构造函数也可能会覆盖全局本机变量。虽然这是非常正确的,但它将产生比仅潜在重写本地全局变量更多的负面影响使用诸如JSHint之类的优秀工具来整理代码(就像您应该做的那样)可以避免这些错误。

这不是完全安全的。当在没有
new
的情况下调用构造函数时,
指向全局对象

var ticket = Ticket(); //this.document will point to the global document object
理解代码的关键在于它使用了
this
,这是一个特殊的关键字,可以表示不同的东西

  • 当不在函数中时,它表示
    窗口
    警报(this.name)
  • 作为独立函数调用时,如果没有附加对象,(
    alert()
    ),
    指向
    窗口
    对象
  • 当使用点语法调用时(
    (ticket.resolve())
    这个
    指向点左边的对象(
    ticket
  • 当作为构造函数(
    new Ticket
    )调用时,
    是一个新的空对象,其原型链中有
    Ticket.prototype
  • 从内联HTML处理程序(
    onclick=“alert(this.id)”
    )调用时,此
    指向附加事件的HTML元素
  • 当从诸如
    setTimeout
    setInterval
    和AJAX回调之类的函数调用时,
    通常指向
    窗口
  • 当使用
    apply
    call
    调用函数时,您可以指定此
    将是什么
  • 您通常可以使用来确保使用正确的
在调用
var ticket=ticket()
的情况下,像
this.name='something'
这样的所有代码都将创建或覆盖现有的全局变量,在这种情况下,就是窗口的
name

如果您关心此问题,可以通过执行以下操作来缓解此问题

    Ticket = function (category, issuedBy, reissuable) {
    if (!this instanceof Ticket) { // called as a function
         return new Ticket(category, issusedBy, reissuable);
    }
    //properties
    this.id = Date.now().toString();
要以通用方式执行此操作,您可以看到以下链接


请注意,这可能是不必要的锅炉板代码,可以通过

您。。。没有覆盖任何内置函数。。。您正在将属性分配给实例化对象
this
。简单的回答是:继续,它不会伤害任何东西。一个较长的答案是:对于长期可维护性来说,这可能是一种不好的做法,但实际上不会造成任何伤害。正确的答案来自@NiettheDarkAbsolRight,我仍在学习JS,但我的理解是,某些函数总是由新对象继承(更令人尴尬的是,我的IDE将这些方法视为现存方法,因此这里有一些推断…)@Jonline我不知道你为什么要更改所选答案?另一个答案并没有带来什么新的东西,实际上比我的答案所包含的信息要少。。。答案中提出的防御性编程解决方案也很糟糕,应该避免使用合适的代码质量工具;你在@JuanMendes的回答中的第二个评论似乎表明你认为他的回答实际上更好(还有,我昨晚基本上是在做这个商业直播,我很确定你的更新答案不是我最初检查的答案;然后,当我注意到胡安的观点,我不会因为切换而受到惩罚时,我没有注意到你已经更新了。老实说,我只是想选择其他人似乎都认为正确的答案赞成。对不起。我会仔细检查你的答案,找到一对可以(有效地)提高投票率以抵消我的混乱的夫妇。:)答案太棒了。谢谢。你也可以创建全局并覆盖它们……添加一个答案是真的,但通常如果你JSHint你的代码;)@plalx,这不会是一个问题,但从技术上讲,这仍然是正确的答案。不幸的是,大多数人都没有提示他们的代码;)+1是的,这肯定是一种可能性,但在这种情况下,它将导致更多只覆盖本地成员的问题。老实说,我真的不喜欢这种防御性编程。如果你使用的是正确的工具,这是你应该做的,那么这根本没有必要,但我同意这是值得一提的。这是一个很好的提示,就像StackOverflow一样,它让人很痛苦,因为你无法在所有地方分发正确的答案,并且已经检查了@JuanMendes,我付不起-2,因为我没有检查我那微不足道的因果报应。但是谢谢你@Jonline我感觉到你了,特别是在大约1公里后你才有很多特权。我不认为你会失去2分,因为你会通过接受一个不同的答案来获得他们?