Объекты и функции в 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; не создает свойство "значение".
Ответы
Ответ 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 - это просто объект (Функция).