根据父对象属性检查时,hasOwnProperty返回true

传说

我的JavaScript代码:

console.clear();

function BaseClass(nname) {
  var name = nname;

  this.bc_PublicProperty = "DefaultValue_BaseClass";

  this.bc_getName = function GetName() {
    return name;
  };

  this.bc_setName = function SetName(nname) {
    name = nname;
  };
}

function SubClass(nname) {
  BaseClass.call(this, nname);

  this.sc_PublicProperty = "DefaultValue_SubClass";

  this.sc_getName = function GetName() {
    return name;
  };

  this.sc_setName = function SetName(nname) {
    name = nname;
  };
}

SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;

var bc = new BaseClass("Anton");
var sc = new SubClass("Bernd");

console.log("hasOwnProperty check on subclass object 'sc' returns true for Method 'bc_getName'");

for (var pro in sc) {
  console.log("Is " + pro + " own property of subclass:  --> " + Object.hasOwnProperty.call(sc, pro));

}

我有两个对象(BaseClass和SubClass)。一个使用构造函数模式从另一个继承,如MDN所述

现在,当我遍历子类对象的所有属性时,对于hasOwnProperty,即使对于父方法/属性,除了构造函数之外,它们都返回true。

这是否意味着在使用构造函数模式时会中断?

当我将公共属性和方法放在构造函数中时,无论是在BaseClass还是SubClass中,它们始终将被“标记”为自己的属性/方法。当我改为将它们附加到各自的原型时,hasOwnProperty将为它们输出“ false”。

无论您将公共方法/属性放在原型中还是在构造函数中本身,都可以在子类(-> SubClass2,-> SubClass3)中使用它们。

唯一的一件事,我现在能想到的,为什么你应该将它们连接到原型对象,是因为效率的原因,如解释在这里,“定义类的方法”部分。为了不为每个构造的实例添加闭包。

值类型应该在原型上声明,而不是声明其初始值取决于构造函数的参数或构造时的其他状态的变量。您可以覆盖两个属性/函数,而不论其声明位置如何。

另外,在原型上设置吸气剂和设置器(例如设置或获取私有变量)是没有意义的,因为私有变量必须是公共的,以便附加到原型的吸气剂和设置器可以访问。

因此,使用getter和setter毫无意义。您可以直接访问公共变量。

我现在必须调整一下我的问题:

我何时需要hasOwnProperty,如果实际上应该在原型上声明公共道具/功能,则所有道具/功能将全部输出Object.hasOwnProperty(obj,“ prop / func”)-> false。给我一个用例,在合理时使用hasOwnProperty。

console.clear();

var l = function(v) {
  console.log(v);
};

function BaseClass(nname) {

  this.bc_nameProp = nname;
  this.bc_ownFunc = function() {
    l("bc_ownFunc of BaseClass called");
  };

  this.bc_getName = function GetName() {
    return this.bc_nameProp;
  };
}

BaseClass.prototype.bc_getName = function GetName() {
  return this.bc_nameProp;
};

BaseClass.prototype.bc_PublicProperty = "DefaultValue_BaseClass";

BaseClass.prototype.bc_setName = function SetName(nname) {
  bc_nameProp = nname;
};

function SubClass(nname) {

  BaseClass.call(this, nname);

  this.sc_setName = function SetName(nname) {
    bc_nameProp = nname;
  };

  this.bc_getName = function GetName() {
    return "xyz";
  };

}

SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;

SubClass.prototype.sc_getName = function GetName() {
  return this.bc_nameProp;
};
SubClass.prototype.sc_PublicProperty = "DefaultValue_SubClass";

var bc = new BaseClass("Anton");
var sc = new SubClass("Bernd");

l("-----  iterating over BaseClass properties  ------");
l("");
for (var pro in bc) {
  l("Is " + pro + " own property of BaseClass:  --> " + Object.hasOwnProperty.call(bc, pro));

}
l("");
l("-----  iterating over SubClass properties  ------");
l("");
for (var p in sc) {
  l("Is " + p + " own property of subclass:  --> " + Object.hasOwnProperty.call(sc, p));

}

l(bc.bc_getName());
l(sc.bc_getName());
l(sc.sc_getName());


当我问这个问题时,我认为在JavaScript中使用经典继承时,可以使用hasOwnProperty来区分子类的哪些属性/函数直接属于它。这是不可能的,因为父原型的所有属性/功能都将复制到SubClass的原型中:

SubClass.prototype = Object.create(BaseClass.prototype);

使用hasOwnProperty时,附加到原型的所有属性/函数都将返回“ false”。

并且,如果您在BaseClass和SubClass的构造函数中声明了公共属性/函数,则在子类上为这些属性调用hasOwnProperty时,所有这些属性都将返回“ true”。

使用以下语句将它们复制到SubClass:

BaseClass.call(this, nname);

因此,在迭代SubClass类型的obj的所有属性时使用hasOwnProperty,对于在原型级别声明的所有属性/函数,将输出false;对于在构造函数级别声明的所有属性/函数,将输出true。

现在,我明白了为什么在这种用例中使用hasOwnProperty没有意义。

MatíasFidemraizer

检查你调用BaseClass.call(this)SubClass的构造,这意味着您要添加BaseClass的属性和功能的SubClass情况下,因为this的一个实例SubClass

这就是为什么hasOwnProperty返回true所有属性的原因。

错误的原型...

最终,您不会利用JavaScript的原型。

必须在原型本身中定义必须作为某些原型的任何实例的一部分的功能

    var A = function() {};

    A.prototype = {
       doStuff: function() {}
    };

实际上,在构造时定义函数的唯一好处是可以确保对象始终定义一些函数/属性,但是一旦创建了对象,就可以确保确定。

对我来说,以下几种定义属性的方式之间有很小的区别:

var A = function() {};
var instance = new A();
instance.text = "Hello, World!";

// or...

var A = function() {
    this.text = "Hello, World!";
};

var instance = new A();

第一个代码示例text在构造函数被调用之后定义属性,而第二个示例在构造函数内部定义属性,但是在两种情况下,thisinstance都是对同一对象(即的实例A的引用

使用原型,您可以确保从某个构造函数创建的所有对象将共享相同的成员,并且这些成员将使用原型链继承和使用

关于OP的更新...

OP说了很多话,但总结说:

[...]我现在必须稍微调整一下我的问题:什么时候需要hasOwnProperty,如果实际上应该在原型上声明公共prop /功能,则所有属性都会依次输出Object.hasOwnProperty(obj,“ prop / func “)->错误。给我一个用例,在合理时使用hasOwnProperty。

你走错路了...为什么在需要的时候hasOwnProperty问自己问自己,何时需要可重用性较低的简单对象,或何时需要实际可重用性。hasOwnProperty与这个问题无关。

当您使用文字对象时(即使用语法声明为原样的对象{})?当您需要字典,参数映射,值对象...时,您喜欢这里,hasOwnProperty因为通常您的接收参数的代码如下所示:

function X(uri, options) {
   if(typeof options != "undefined") {
       // For example, we set a default value if options has no
       // mimeType property...
       options.mimeType = options.hasOwnProperty("mimeType") ? options.mimeType : "application/json";
   }
}

何时使用原型使用复杂的对象?在定义行为时,您需要在整个应用程序甚至多个应用程序中重用它,并且还需要在通用需求(hello继承之上添加更多行为

关于为什么使用hasOwnProperty...

OP说:

但是,如果要检查属性是否存在,为什么还要在此处使用“ hasOwnProperty”?不应该是:options.mimeType = options.mimeType || “ application / json”;

互联网上有很多代码在执行ʻoptions.mimeType =

options.mimeType || “ application / json” , right, because in JavaScript undefinedevaluates to错误(if选项doesn't own amimeType property returnsundefined`)。

以我的拙见,我会使用hasOwnProperty因为它返回一个boolean存在的值或存在的值,并且其值未定义。

例如,可以将选项定义为{ mimeType: undefined },有时您想知道该属性是否存在,即使它具有undefined值。undefined作为false治疗的情况下,如果是不确定的,或者如果它存在与否,做X,并且hasOwnProperty我想确保它具有财产或没有

那么,为什么还要使用options.hasOwnProperty其他方法呢?容易:因为语言提供了一种工具来验证某个对象中是否存在属性,所以为什么需要技巧?object.hasOwnProperty返回truefalse,即使该属性具有undefined,我也可以确定该属性是否存在

随着options.hasOwnProperty("mimeType")我可以抛出Error,如果它存在,它有一个undefined值。我为什么更喜欢这个?因为我喜欢快速失败的概念:如果您为我提供了具有undefined价值的财产,我倾向于认为您的代码中存在一些错误。定义或不定义,我的朋友!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Ruby根据属性在数组中查找和返回对象

Java 11 Lambda-检查每个对象,在满足第一个条件时返回true,否则返回false

仅当value为true时才返回对象键

当属性存在时,为什么猫鼬模型的hasOwnProperty返回false?

迭代对象数组时返回false或true

javascript根据条件从对象的嵌套数组返回属性值

使用SightEngine API时,“检查”对象没有属性“图像”

根据ajax响应,在提交按钮单击时返回true / false

根据属性对对象进行排序,返回内存地址

用hasOwnProperty检查遍历对象?

根据属性返回对象值

根据属性值从JObject返回子对象

根据错误对象集合中值为true的属性进行过滤

根据属性值返回过滤的Java对象列表

空对象在检查时返回false

创建对象时返回true / false

活动模型-根据子属性设置父对象的属性

当对象[sqrt 2 ^ 2] == 2时R不返回true

AngularJS:当检查对象为null时,返回错误消息

当hasOwnProperty()为false时,遍历继承的对象属性

验证函数在错误检查时返回 undefined 而不是 true

根据属性从列表中返回一个随机对象

hasOwnProperty('getTime') 在日期对象上返回 false

在java中访问对象属性时避免空检查

如何使用数组包含并根据对象的属性检查对象

当值与数组对象匹配时 inArray 不返回 true

Linq:匹配子对象列表中子对象的属性并从父对象列表中返回父对象

如何根据提供的参数键入返回对象属性的函数?

检查每个对象,满足第一个条件时返回 true,否则返回 false