构造函数的对象字面量返回 toString() 方法,但不返回其他方法

发布于 2024-09-05 14:54:36 字数 1432 浏览 4 评论 0 原文

我对对象中定义的 JavaScript 方法和 this 关键字感到非常困惑。

在下面的示例中,当 Mammal 对象实例化时,会调用 toString() 方法:

function Mammal(name){ 
  this.name=name;
  this.toString = function(){
    return '[Mammal "'+this.name+'"]';
  }
}

var someAnimal = new Mammal('Mr. Biggles');
alert('someAnimal is '+someAnimal);

尽管事实上并未调用 toString() 方法在对象 someAnimal 上,如下所示:

alert('someAnimal is '+someAnimal.toString());

它仍然返回 'someAnimal is [Mammal "Mr. Biggles"]'。这对我来说没有意义,因为 toString() 函数没有在任何地方被调用。

然后,如果我将 toString() 方法更改为我编写的方法,例如 random()

function Mammal(name){ 
  this.name=name;
  this.random = function(){
    return Math.floor(Math.random() * 15);
  }
} 

var someAnimal = new Mammal('Mr. Biggles');
alert(someAnimal); 

它会完全忽略 random< /code> 方法(尽管它的定义方式与 toString() 方法相同)并返回:[object object]

我遇到的另一个问题难以理解继承的是 this 的值。例如,在下面的示例中,

function person(w,h){
  width.width = w;
  width.height = h;
}

function man(w,h,s) { 
  person.call(this, w, h); 
  this.sex = s;
}

this 关键字被清楚地发送到 person 对象。但是,当 person 对象接收到 this 时,它引用的是子类 man 还是超类 person 呢?

感谢您消除了我对 JavaScript 中的继承和对象文字的任何困惑。

I'm very confused with JavaScript methods defined in objects and the this keyword.

In the below example, the toString() method is invoked when Mammal object instantiated:

function Mammal(name){ 
  this.name=name;
  this.toString = function(){
    return '[Mammal "'+this.name+'"]';
  }
}

var someAnimal = new Mammal('Mr. Biggles');
alert('someAnimal is '+someAnimal);

Despite the fact that the toString() method is not invoked on the object someAnimal like this:

alert('someAnimal is '+someAnimal.toString());

It still returns 'someAnimal is [Mammal "Mr. Biggles"]'. That doesn't make sense to me because the toString() function is not being called anywhere.

Then to add even more confusion, if I change the toString() method to a method I make up such as random():

function Mammal(name){ 
  this.name=name;
  this.random = function(){
    return Math.floor(Math.random() * 15);
  }
} 

var someAnimal = new Mammal('Mr. Biggles');
alert(someAnimal); 

It completely ignores the random method (despite the fact that it is defined the same way was the toString() method was) and returns: [object object]

Another issue I'm having trouble understanding with inheritance is the value of this. For example, in the below example

function person(w,h){
  width.width = w;
  width.height = h;
}

function man(w,h,s) { 
  person.call(this, w, h); 
  this.sex = s;
}

this keyword is being sent to the person object clearly. However, does this refer to the subclass man or the superclass person when the person object receives it?

Thanks for clearing up any of the confusion I have with inheritance and object literals in JavaScript.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忘东忘西忘不掉你 2024-09-12 14:54:36

您在使用 toString 方法时遇到的行为是因为当您执行字符串连接时,对象会隐式转换为 String(通过ToPrimitive 内部操作,使用提示类型“细绳”)。

该方法调用另一个内部操作 [[DefaultValue]](hint )

如果提示类型是String,则该操作显式获取toString属性并调用它。

如果您的对象没有显式定义 toString 方法,该方法仍会在原型链中的更高层解析,"[object Object]" 是 < a href="http://bclary.com/2004/11/07/#a-15.2.4.2" rel="nofollow noreferrer">Object.prototype.toString 方法。

例如:

var obj = {
  toString:function () {
    return "hello";
  }
};

alert(obj + ' world');
// will alert "hello world"

现在,关于 this 值:

构造对象的方式也称为构造函数链this 值将引用到一个新对象,该对象继承自您使用 new 运算符调用的构造函数原型。

使用 call 调用另一个构造函数只会使得对被调用函数内的 this 值进行的所有属性分配实际上都是从第一个对象开始对新对象进行的构造函数,这并不真正影响原型链,例如:

function Person(w,h){
  this.width = w;
  this.height = h;
}

function Man(w,h,s) { 
  Person.call(this, w, h); // will just apply the width and height assignments
  this.sex = s;
}

var person = new Person(1,2);
person instanceof Person; // true
person instanceof Man; // false

var man = new Man(1,2,3);
person instanceof Person; // false
person instanceof Man; // true

编辑:为了澄清更多,当您调用 Person.call(this, ...); 时只需调用该函数来对该函数的 this 值(示例中的 this.widththis.height)的属性进行赋值,作为 call 第一个参数传递的对象,一个简化的示例:

function Test () {
  this.foo = 1;
  this.bar = 2;
  this.baz = 3;
}

var obj = { foo: 0 }; // a simple object
Test.call(obj);
// now obj looks like this: {foo: 1, bar: 2,baz: 3}

The behavior you are experiencing with the toString method is caused because when you do a string concatenation, the object is converted implicitly to String (by the ToPrimitive internal operation, using hint type "String").

That method invokes another internal operation, [[DefaultValue]](hint).

If the hint type is String, that operation explicitly gets the toString property and invokes it.

If your object doesn't explicitly define a toString method, the method will still be resolved higher in the prototype chain, "[object Object]" is the result of the Object.prototype.toString method.

For example:

var obj = {
  toString:function () {
    return "hello";
  }
};

alert(obj + ' world');
// will alert "hello world"

Now, about the this value:

The way you are constructing your objects is also known as constructor chaining, the this value will refer to a new object that inherits from the constructor's prototype that you called with the new operator.

The invocation of the other constructor with call will just make that all the property assignments made to the this value inside the called function, are actually made on the new object from the first constructor, that doesn't really affect the prototype chain, for example:

function Person(w,h){
  this.width = w;
  this.height = h;
}

function Man(w,h,s) { 
  Person.call(this, w, h); // will just apply the width and height assignments
  this.sex = s;
}

var person = new Person(1,2);
person instanceof Person; // true
person instanceof Man; // false

var man = new Man(1,2,3);
person instanceof Person; // false
person instanceof Man; // true

Edit: To clarify more, when you invoke Person.call(this, ...); it just calls that function to make the assignments of properties of the this value (this.width and this.height on your example) on that function, to the object passed as the first argument of call, a simplified example:

function Test () {
  this.foo = 1;
  this.bar = 2;
  this.baz = 3;
}

var obj = { foo: 0 }; // a simple object
Test.call(obj);
// now obj looks like this: {foo: 1, bar: 2,baz: 3}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文