我对于在对象中定义的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);
尽管事实上没有在对象someAnimal上调用toString()方法,如下所示:
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);
它完全忽略了随机方法(尽管它的定义方式与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对象。但是,当人物对象接收它时,“this”是指子类(man)还是超类(person)?
感谢您清除我在javascript中对继承和对象文字的任何困惑。
答案 0 :(得分:3)
导致toString
方法遇到的行为是因为当您执行字符串连接时,该对象将隐式地转换为String(由ToPrimitive
内部操作,使用提示类型“String”)。
该方法调用另一个内部操作[[DefaultValue]](hint)
。
如果提示类型是String,则该操作显式获取toString
属性并调用它。
如果您的对象未明确定义toString
方法,则该方法仍会在原型链中更高地解析,"[object Object]"
是Object.prototype.toString方法的结果。
例如:
var obj = {
toString:function () {
return "hello";
}
};
alert(obj + ' world');
// will alert "hello world"
现在,关于this
值:
构建对象的方式也称为构造函数链接,this
值将引用一个新对象,该对象继承自您使用{{{0}调用的构造函数的原型1}} operator。
使用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.width
的属性关于该函数的this.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}