Функции и объекты JavaScript, использующие ключевое слово this, не работают

мой вопрос здесь о функциях и объектах в JavaScript. У меня есть три вопроса, которые связаны между собой. В приведенном ниже примере я пытаюсь получить доступ к значению «а» в тесте, но я получаю неопределенный. но я создаю новый объект теста, затем я могу получить доступ к «а» оценить и изменить его.

//create a function called test
         var test=function() {
           this.a=2
           this.b=3 };
           test.a//undefined
//create a object called test1 using 'new'
test1 = new test();
test1.a//2
//change the value of a in test1
test1.a=4
test1 //Object { a=4, b=3}

пытаясь выяснить, почему это происходит, я наткнулся на этофункции JavaScript являются объектами? и еще один вопрос возник из этого. Принятое решение для этого вопроса SO ниже

var addn = function func(a) {
  return func.n + a;
};

addn['n'] = 3;
addn(3);

Я изменилfunc.n» кэтот' и это больше не работает

var addn=function func(a) {
 return this.n+a;
};
addn['n']=3;
addn(3); //NaN

сделать анонимную функцию с 'этот' тоже не помогло

    //anonymous function
var addn=function(a) {
     return this.n+a;
    };
    addn['n']=3;
addn(3); //NaN

зачем использоватьэтот' не работал?

последний вопрос: в чем разница в использовании ключевого слова?новый» а также 'CreateObject», Дуглас Крокфорд предлагает использоватьCreateObject» в своей книге, но я не понимаю, почему. Спасибо всем за ваши комментарии

Ответы на вопрос(2)

Решение Вопроса
1. Функции являются конструкторами для новых объектов

Когда вы звонитеnew FuncNameфункция действует как конструктор, а значениеthis внутри указывает на строящийся объект (а не на саму функцию). Когда вы удалите,newthis становитсяundefinedотступая к глобальному объекту (если выв строгом режиме).

2. Функции также являются объектами

Каждая функция является экземпляромFunctionпоэтому сами функции являются объектами и могут иметь свои свойства. Эти свойства не могут быть доступны сthis.propName внутри тела функции, только сfuncName.propName, Тот'потому чтоthis внутри функцияникогда сам объект функции (если вы не заставили его быть, с,bindcall, или жеapply).

Я надеюсь, что обе темы выше помогут вам понять, как работают функции. Что касается вашего последнего вопроса: КрокфордаcreateObject это другой способ реализации наследования, делая в основном то, чтоObject.create делает в ES5-совместимых браузерах. Это позволяет объекту наследовать прямо от другого объекта, не требуя от вас создания нового конструктора вручную, установите егоprototype свойство (которое является примером свойства объекта-функции) и создайте экземпляр сnew, Крокфорд предпочитает это и говорит, что перестал использоватьnew в пользу этого подхода.

В ответ на вопросы, которые вы задали в чате, приведена попытка объяснить, что такое функции и что они делают, с помощью примеров.

Функции могут быть просто ... функциями

Вы звоните им, они что-то делают

function alertThis(what) {
    alert(what)
}
alertThis("alerting something");

Вы также можете передать им значения, и они возвращают значения

function timesTwo(num) {
    return num * 2;
}
timesTwo(2); // 4

Их можно сдать и вернутьчто-нибудь, в том числе объекты ...

function createPerson(firstName, lastName) {
    return {
        firstName : firstName,
        lastName : lastName
    }
}
var john = createPerson('John', 'Doe');
john.lastName; // "Doe"

... и другие функции:

function timesN(n) {
    return function(num) {
        return n * num;
    }
}
var timesThree = timesN(3);
timesThree(5); // 15
функцииявляются объекты

Функции могут передаваться и возвращаться как любой обычный объект. Тот'потому что ониявляются объекты. Как и любой объект, они могут иметь свойства:

function countCalls() {
    countCalls.timesCalled++;
}
countCalls.timesCalled = 0;
countCalls();
countCalls();
countCalls.timesCalled; // 2

Одним из очень важных свойств по умолчанию функций являетсяprototype, Это'особая собственность, и мыпосмотрим почему.

Функции могут выступать в качестве конструкторов для новых объектов

Функции могут вести себя так же, как конструкторы классов в обычных ОО-языках.Когда вызывается сnewони создают новый объект определенного "учебный класс", Этот новый объект называетсяthis внутри функции и автоматически возвращается:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}
var john = new Person('John', 'Doe');
john.firstName; // "John"
john instanceof Person; // true

... если вы сознательно не вернете что-то еще:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    var fakePerson = {
        firstName : firstName,
        lastName : lastName
    };
    return fakePerson;
}
var notPerson = new Person('John', 'Doe');
notPerson.firstName; // "John"
notPerson instanceof Person; // false
// Note: the object called 'this' inside the function is created, but
// after the function is called there is no outside reference to it.
Объекты, созданные конструкторами, знают, кто их создал, и могут видеть ихprototype имущество

Вернуться к реальному человеку:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

// Add something to the Person prototype
Person.prototype.sayHi = function() {
    return "hi, I'm " + this.firstName;
}

var john = new Person('John', 'Doe');
john.sayHi(); // "Hi, I'm John"
john.constructor; // Person

Предметjohn МожноsayHi() потому что он имеет доступ ко всему внутри его конструктораprototype имущество. Но он не может видеть другие свойства человека напрямую (только через своиconstructor имущество):

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    Person.timesCalled++;
    // There is no 'this.timesCalled', only Person.timesCalled
}
Person.timesCalled = 0;
var john = new Person('John', 'Doe');
john.timesCalled; // undefined - john cannot be called, Person can
john.constructor.timesCalled; // 1
 bfavaretto19 июн. 2013 г., 23:50
 bfavaretto19 июн. 2013 г., 23:28
Когда вы вызываете функцию безnew, Это'не вызывается как конструктор, иthis не устанавливается для объекта, который создается (так как его нет). Следующий код создаст глобальную переменную с именем:barfunction foo(){this.bar = true}; foo();, так какthis будет означать глобальный объект (window).
 brain storm21 июн. 2013 г., 21:21
Ваше объяснение выше очень полное. Можете ли вы дать одну иллюстрацию, где с помощью ключевого словаnew а такжеobject.create будет иметь значение. Я читал где-то здесь, используяnewвсе клонируется в объект от родителя, но с помощьюobject.create только прототипы, но не свойства, которые наследуются. что это значит, если это правильно, любая иллюстрация здесь очень поможет. Еще раз большое спасибо. ты обалденный!!
 bfavaretto21 июн. 2013 г., 21:29
@ user1988876 Мои объяснения уже далеко ушли от первоначального объема вашего вопроса. Если у вас есть сомнения по поводу new против Object.create, поищите ответы на этом сайте и / или оставьте отдельный вопрос.
 bfavaretto21 июн. 2013 г., 23:28
 brain storm21 июн. 2013 г., 22:22
@bfaveretto. Я сделаю это. можете ли вы прокомментировать первый вопрос выше после "продолжить это обсуждение в чате, Это поможет увидеть, было ли мое понимание ясным. извините и большое спасибо
 brain storm19 июн. 2013 г., 23:37
+2: Еще раз спасибо за разъяснения. в этом примере var obj = function () {this.x = 1; return {increment: function () {this.x = this.x + 1; }}}; var test1 = new obj (); test1.x // undefined ... но когда я удаляю секцию return return и просто получаю var obj = function () {this.x = 1; }; var test1 = new obj (); test1.x // 1 ... почему наличие оператора return не разрешает доступ к x ..
 bfavaretto19 июн. 2013 г., 23:32
Разница между использованиемObject.create или жеnew имеет больше общего снаследование.Object.create просто позволяет настроить наследование менее многословно (если вы нене нужен конструктор).
 brain storm19 июн. 2013 г., 23:22
Спасибо, Бфаваретто. теперь я понимаю, чтоэтот' указывает на создаваемый объект. Можете ли вы объяснить, что вы подразумеваете под "когда вы удаляете новое, 'этот' становится неопределенным ... » а что касается object.create и new, означает ли это, что каждый раз, когда объект создается с использованием new, его прототип должен быть инициализирован, могу ли я не включить его в саму новую конструкцию, поместив методы функции внутри самой функции main? еще раз спасибо
 bfavaretto19 июн. 2013 г., 23:42
@ user1988876 Потому что в этом случае конструктор не возвращает объект, который он создавал, а новый, который вы сказали ему вернуть;this внутри конструктор ссылается на первое.
 brain storm21 июн. 2013 г., 21:18
Спасибо, Бфаваретто. Во втором примере в разделе выше наFunctions can act as constructors for new objects, Вы возвращаетесьfakeperson, Затем, когда вы создаете новый объектnotPersonнам нужноnew ключевое слово, так какPerson вернутьfakeperson, Вы также упоминаетеthe object called 'this' inside the function is created, but after the function is called there is no outside reference to it, Так как мы возвращаемся,this уничтожается после вызова функции rite, если нет возврата, тоthis сохранились.
 brain storm19 июн. 2013 г., 23:49
Продолжая то, что вы сказали, я сделал одно изменение строки здесь: var obj = function () {this.x = 1; return {increment: function () {this.x = this.x + 1; return this.x;}}}; test1 = new obj (); var c = test1.increment (); c; // теперь значение c равно NaN. Я не понимаю, почему это NaN

1. addn ['n'] = 3; // Означает, что вы добавляете статическое свойство n в функцию (объект) addn. так addn.n также работает.

2 this.n означает свойство n экземпляра. this.n === undefined, поэтому он возвращает NaN.

3 var addn = function func (a) означает, что вы даете второму имени func. var addn = function (a) - лучший формат в большинстве случаев.

4 createObject не является родным кодом javaScript. 'Новый» является.

Ваш ответ на вопрос