Литерал объекта функции конструктора возвращает метод toString (), но не другой метод - PullRequest
0 голосов
/ 13 июня 2010

Я очень запутался в методах javascript, определенных в объектах, и в ключевом слове "this".

В приведенном ниже примере метод toString () вызывается при создании экземпляра объекта Mammal:

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); 

Он полностью игнорирует случайный метод (несмотря натот факт, что он определен так же, как и метод toString (), и возвращает: [объектный объект]

Еще одна проблема, с которой я не могу разобраться с наследованием, - это значение "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.Однако относится ли это к подклассу (человек) или к суперклассу (человек), когда объект человека получает его?

Спасибо за устранение путаницы с литералами наследования и объектов в javascript.

1 Ответ

3 голосов
/ 13 июня 2010

Поведение, которое вы испытываете при использовании метода toString, вызвано тем, что при выполнении конкатенации строк объект неявно преобразуется в строку (с помощью 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 будет ссылаться на новый объект, который наследует от прототипа конструктора, который вы вызвали с помощью оператора 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}
...