Подтвердить что ты не робот

Объекты и функции в javascript

Возможный дубликат:
Javascript: мне нужно поместить this.var для каждой переменной в объекте?

Я пытаюсь понять функции и объекты в javascript. Говорят, что также функции - это объекты и объекты, которые являются "ассоциативными массивами", то есть коллекциями пар ключ-значение. Я понимаю, что если я напишу

function myFunction() {
    var value = 0;
}
alert(myFunction.value); //then this gives me "undefined"

поскольку переменные имеют область действия. Но если я пишу

function myFunction() {
    this.value = 0;
}
alert(myFunction.value); //then this gives me "undefined" too.

Но, наконец, если я пишу

function myFunction() {
    this.value = 0;
}
myFunction.value = 0;
alert(myFunction.value); //then this gives me 0

Поэтому я могу присвоить свойство myFunction "значение", но из "снаружи". Может кто-нибудь объяснить, что происходит и почему this.value = 0; не создает свойство "значение".

4b9b3361

Ответ 1

Посмотрите на все три случая индивидуально:

function myFunction()
{
    var value = 0;
}

Здесь вы объявляете переменную в области функций. Каждый раз, когда вызывается функция, будет создана переменная (и память будет выделена). Когда функция возвращается, переменная выходит за пределы области действия - переменная value помечена и будет GC'ed. Область не может быть доступна из области "выше", чем эта область функций... если эта функция определяет функцию внутри своей области действия, эта функция будет иметь доступ к переменной value (посмотрите на закрытие для более подробной информации). Нижняя строка: переменная существует только при вызове функции и не будет существовать после возвращения функции.

function myFunction()
{
    this.value = 0;
}

Здесь вы определяете функцию, которая может быть конструктором, методом, обработчиком событий или комбинацией всех вышеперечисленных. this - это ссылка, которая укажет на контекст, в котором вызывается функция. Этот контекст определяется "ad hoc" и может варьироваться:

myFunction();// global scope, this points to window
var anObject = {method: myFunction};
anObject.method();//called in the object context, this points to object
console.log(abObject.value);//logs 0
var instance = new myFunction();//as constructor
console.log(instance.value);//logs 0
document.getElementById('anInputField').onclick = myFunction;//on click, value will be set to 0

В последнем случае:

function myFunction()
{
    this.value = 0;
}
myFunction.value = 0;

Это не имело бы никакого значения, если бы вы написали это:

function myFunction()
{}
myFunction.value = 0;

Потому что, как я объяснил выше: this ссылается на любой контекст во время вызова функции. Это не должно быть myFunction, на самом деле: чаще всего это не будет:

var anObject = {method: myFunction};
myFunction.value = 101;//myFunction.value is changed
anObject.method();
console.log(anObject.value);//0 -> the function still sets the value property to 0

Если вы хотите получить доступ к свойствам функции внутри этой функции, самый простой способ - ссылаться на эту функцию как на любой другой объект:

function myFunction()
{
    this.value = myFunction.value;
}
myFunction.value = 101;

Внимание:
Просто дружественное предупреждение: неэффективно использовать this в функциях без проверки на глобальные переменные... Если функция вызывается без явного контекста, JS по умолчанию использует глобальный объект (window). Это означает, что каждая строка, которая присваивает свойство любому объекту this, тоже будет указывать, будет устанавливать глобальную переменную:

function myFunction()
{
    this.foo = 'bar';
}
myFunction();
console.log(window.foo);//logs bar EVIL GLOBAL

Несколько способов предотвратить загромождение глобального объекта с помощью глобальных переменных:

function mySafeFunction()
{
    'use strict';//throws errors, check MDN
    //this defaults to null, instead of window
    impliedGlobal = 'Error';//doesn't work
    this.onGlobal = 'Error';//null.property doesn't work
}
//same goes for constructors, but a more precise check can be used, too (and works on older browsers)
function SafeConstructor()
{
    if (!(this instanceof SafeConstructor))
    {//this doesn't point to SafeConstructor if new keyword wasn't used
        throw new Error('Constructor wasn\'t called with new keyword');
        //or "correct" the error:
        return new SafeConstructor();
    }
    console.log(this);// will always point to the SafeConstructor object
}

Ответ 2

Вам нужно создать instance с помощью ключевого слова new.

function myFunction() {
    this.value = 0;
}

var inst1 = new myFunction();

alert(inst1.value);  // this works

Теперь это соответствует текущему объекту и получает соответствующее значение свойства.

Check Fiddle

В конце дня функции остаются объектами. Поэтому он не жалуется, когда вы назначаете myFunction.value = 0. Это может сбивать с толку, поскольку вы используете значение ( ключ) как внутри, так и снаружи функции.  Замените его

myFunction.abc = 'Hello' 
alert(myFunction.abc) still works

Но он не будет отражен внутри фактической myFunction, поскольку вы еще не вызвали функцию.

Ответ 3

Вы неправильно поняли концепт прототипа/объекта javascript.

В первом примере вы правы, переменная имеет область видимости

Второй пример неверен. Если вы хотите использовать функцию как "класс", вы должны создать из нее объект

function myFunction() { this.value = 0; }
var test = new myFunction;

только тогда вы можете получить доступ к свойству 'value'. для каждого нового оператора создается новый объект.

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

Надеюсь, что это помогло

Ответ 4

Не уверен, что я смогу прояснить все нюансы, но это может пролить свет:

function myFunction() {
    this.value = 0;
}
alert( (new myFunction).value);

Использование ключевого слова new создает новый "экземпляр" myFunction, позволяющий использовать this для назначения значения изнутри функции.

Ответ 5

myFunction - это объект функции. Вы можете передать его, присвоить его переменным, присвоить ему свойства, и вы можете его вызвать.

Назначение свойств работает как с любым другим объектом:

myFunction.value = 0;

Но обратите внимание, что на данный момент у вас еще не вызвана функция, поэтому код внутри функции (var value = 0; или this.value = 0;) еще не выполнен. Рассмотрим это:

function someFunction() {
    window.foo = 'foo'; // create a global variable
}

someFunction.bar = 'bar';

console.log(someFunction.bar); // 'bar'
console.log(window.foo); // undefined

someFunction(); // execute the function

console.log(someFunction.bar); // 'bar'
console.log(window.foo); // 'foo'

Когда вы выполняете функцию с помощью myFunction(), только тогда создается локальная переменная/свойство устанавливается на this. То, к чему относится this, зависит от того, как функция вызывается и хорошо объясняется в документации MDN. this никогда относится к самой функции, если вы явно не задали ее так.

Ответ 6

В javascript любая функция также является объектом, они являются объектами Function, так же как Number, Object, Array

Одна сложная вещь - это слово new, затем префикс перед функцией, он создает новый объект и делает указатель ключевого слова this для этого нового объекта (еще один, он назначает прототип функции к новому объекту __ proto __).
В функции

this.value = 0;

создаст новое свойство value для нового объекта и назначит ему 0.

Если перед функцией есть нет new, это вызов функции, а this будет указывать на объект Окно.

Попробуйте console.dir(this); в функции, вы увидите разницу.

myFunction.value = 0;

создаст свойство value to myFunction и назначит ему 0. Поскольку myFunction - это просто объект (Функция).