Object和String原型不是已定义字符串的原型?

时间:2016-12-13 17:26:11

标签: javascript inheritance prototype

我正在尝试理解JavaScript基于原型的继承是如何工作的。我期待以下输出将评估为true。这是为什么?

var myStr = "Sample";
String.prototype.isPrototypeOf(myStr); // false
Object.prototype.isPrototypeOf(myStr); // false

3 个答案:

答案 0 :(得分:4)

JavaScript具有原始字符串和字符串对象。你在那里写的是一个原始字符串。 <{3}}方法总是为任何原语返回false,因此您的结果是有意义的。

如果您使用字符串对象,则会获得true

&#13;
&#13;
var myStr = new String("Sample");
console.log(String.prototype.isPrototypeOf(myStr)); // true
console.log(Object.prototype.isPrototypeOf(myStr)); // true
&#13;
&#13;
&#13;

您可能想知道:如果它是原语,那么为什么我可以调用String.prototype上定义的方法?

答案是规范定义如果在原始字符串上使用属性访问器,则会创建具有等效字符序列的临时字符串 object (以String.prototype为原型然后,从该临时对象读取属性。 (数字也是如此。)

我们可以通过向返回该对象的String.prototype添加方法来创建临时对象(仅用于说明目的):

&#13;
&#13;
Object.defineProperty(String.prototype, "foo", {
  value: function() {
    return this;
  }
});
var primitive = "string";
var object = primitive.foo();
console.log(primitive === object);                      // false
console.log(primitive == object);                       // true
console.log(String.prototype.isPrototypeOf(primitive)); // false
console.log(String.prototype.isPrototypeOf(object));    // true
&#13;
&#13;
&#13;

答案 1 :(得分:2)

这是因为string primitives are not string objects。如果您希望上述代码有效,则应通过String类构建字符串,如:

var myStr = new String("Sample");
String.prototype.isPrototypeOf(myStr); // true

答案 2 :(得分:2)

基本上,isPrototypeOf仅适用于对象,字符串基元不是对象,它们是基元。

如果您使用的是String包装器对象,它可以正常工作(但不要这样做!):

&#13;
&#13;
var myStr = new String("Sample");
console.log(String.prototype.isPrototypeOf(myStr)); // true
console.log(Object.prototype.isPrototypeOf(myStr)); // true
&#13;
&#13;
&#13;

但是包装器对象通常是不好的做法,所以不要使用它们。

或者,您可以在测试时将它们转换为对象形式。

&#13;
&#13;
var myStr = "Sample";
console.log(String.prototype.isPrototypeOf(Object(myStr))); // true
console.log(Object.prototype.isPrototypeOf(Object(myStr))); // true
&#13;
&#13;
&#13;