我对对象中定义的 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.
发布评论
评论(1)
您在使用
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 方法。例如:
现在,关于
this
值:构造对象的方式也称为构造函数链,
this
值将引用到一个新对象,该对象继承自您使用new
运算符调用的构造函数原型。使用
call
调用另一个构造函数只会使得对被调用函数内的this
值进行的所有属性分配实际上都是从第一个对象开始对新对象进行的构造函数,这并不真正影响原型链,例如:编辑:为了澄清更多,当您调用
Person.call(this, ...);
时只需调用该函数来对该函数的this
值(示例中的this.width
和this.height
)的属性进行赋值,作为call
第一个参数传递的对象,一个简化的示例: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 theToPrimitive
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:
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 thenew
operator.The invocation of the other constructor with
call
will just make that all the property assignments made to thethis
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:Edit: To clarify more, when you invoke
Person.call(this, ...);
it just calls that function to make the assignments of properties of thethis
value (this.width
andthis.height
on your example) on that function, to the object passed as the first argument ofcall
, a simplified example: