Создание свойств для функций javascript [duplicate]

Посмотрите на этот пример:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

Как вы можете видеть, getJoke возвращает разрешенное обещание (оно разрешено при возврате res.data.value). Таким образом, вы ждете, пока запрос $ http.get не будет завершен, а затем выполнится console.log (res.joke) (как обычный асинхронный поток).

Это plnkr:

http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/

1086
задан JJJ 8 February 2015 в 17:10
поделиться

20 ответов

1162
ответ дан 18 revs, 4 users 56% 29 August 2018 в 01:27
поделиться

Даниэль, удивительное объяснение! Несколько слов по этому и хорошему списку указателя контекста выполнения this в случае обработчиков событий.

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

Для обработчиков событий: встроенный обработчики событий, такие как <element onclick="foo">, переопределяют любые другие обработчики, прикрепленные ранее и раньше, поэтому будьте осторожны, и лучше не вмешиваться в встроенное делегирование событий. И благодаря Заре Алавердян, которая вдохновила меня на этот список примеров через несогласие обсуждение:)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = '#fff';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener('click',foo,false) // in the foo - obj
  • el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
  • <button onclick="this.style.color = '#fff';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
7
ответ дан Arman McHitarian 29 August 2018 в 01:27
поделиться
7
ответ дан Arup Hore 29 August 2018 в 01:27
поделиться

Значение «this» зависит от «контекста», в котором выполняется функция. Контекстом может быть любой объект или глобальный объект, т. Е. Окно.

Таким образом, семантика «этого» отличается от традиционных языков ООП. И это вызывает проблемы: 1. когда функция передается другой переменной (скорее всего, обратный вызов); и 2. когда замыкание вызывается из метода-члена класса.

В обоих случаях это устанавливается в окно.

3
ответ дан Bhargav Rao 29 August 2018 в 01:27
поделиться

Поскольку этот поток наткнулся, я собрал несколько точек для новых читателей в this.

Как определено значение this?

Мы используем это подобно тому, как мы используем местоимения в естественных языках, таких как английский: «Джон работает быстро, потому что он пытается поймать поезд». Вместо этого мы могли бы написать «... Джон пытается поймать поезд ».

var person = {    
    firstName: "Penelope",
    lastName: "Barrymore",
    fullName: function () {

    // We use "this" just as in the sentence above:
       console.log(this.firstName + " " + this.lastName);

    // We could have also written:
       console.log(person.firstName + " " + person.lastName);
    }
}

this не присваивается значение, пока объект не вызовет функцию, в которой он определен. В глобальной области действия все глобальные переменные и функции определяются на объекте window. Следовательно, this в глобальной функции относится к (и имеет значение) глобальный объект window.

Когда use strict, this в глобальном и в анонимных функциях, не связанных с каким-либо объектом, имеет значение undefined.

Ключевое слово this g0] наиболее непонятно , когда: 1) мы используем метод, который использует this, 2) мы назначаем метод, который использует this для переменной, 3) функция, которая использует this, передается как функция обратного вызова и 4) this используется внутри замыкания - внутренней функции. (2)

table [/g10]

Что содержит будущее

Определено в сценарии ECMA 6 , стрелка- функции принимают привязку this из охватывающей (функциональной или глобальной) области.

function foo() {
     // return an arrow function
     return (a) => {
     // `this` here is lexically inherited from `foo()`
     console.log(this.a);
  };
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };

var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!

Хотя функции-стрелки предоставляют альтернативу использованию bind(), важно отметить, что они по существу отключают традиционный механизм this в пользу более широкого понимания лексического охвата. (1)


Ссылки:

  1. this & amp; Object Prototypes, автор Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Ангус Кролл - http: // goo .gl / Z2RacU
13
ответ дан carlodurso 29 August 2018 в 01:27
поделиться

this - одна из неправильно понятых концепций в JavaScript, потому что она ведет себя совсем не так, как с места на место. Просто this ссылается на «владельца» функции, которую мы сейчас выполняем.

this помогает получить текущий объект (контекст выполнения a.k.a.), с которым мы работаем. Если вы понимаете, в каком объекте выполняется текущая функция, вы можете легко понять, что текущий this is

var val = "window.val"

var obj = {
    val: "obj.val",
    innerMethod: function () {
        var val = "obj.val.inner",
            func = function () {
                var self = this;
                return self.val;
            };

        return func;
    },
    outerMethod: function(){
        return this.val;
    }
};

//This actually gets executed inside window object 
console.log(obj.innerMethod()()); //returns window.val

//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val

console.log(obj.outerMethod()); //returns obj.val

Выше мы создаем 3 переменные с одинаковым именем «val». Один в глобальном контексте, один внутри obj и другой внутри innerMethod obj. JavaScript разрешает идентификаторы в определенном контексте, поднимая цепочку областей действия из локального глобального.


Несколько мест, где this можно дифференцировать

Вызов метода объекта

var status = 1;
var helper = {
    status : 2,
    getStatus: function () {
        return this.status;
    }
};

var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2

var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1

Когда line1, JavaScript устанавливает контекст выполнения (EC) для вызова функции, устанавливая this объекту, на который ссылается все, что было до последнего «.». поэтому в последней строке вы можете понять, что a() был выполнен в глобальном контексте, который является window.

С конструктором

this можно использовать для ссылки на создаваемый объект

function Person(name){
    this.personName = name;
    this.sayHello = function(){
        return "Hello " + this.personName;
    }
}

var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott

var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined

Когда выполняется новый Person(), создается совершенно новый объект. Вызывается Person и его this установлен для ссылки на этот новый объект.

Вызов функции

function testFunc() {
    this.name = "Name";
    this.myCustomAttribute = "Custom Attribute";
    return this;
}

var whatIsThis = testFunc();
console.log(whatIsThis); //window

var whatIsThis2 = new testFunc();
console.log(whatIsThis2);  //testFunc() / object

console.log(window.myCustomAttribute); //Custom Attribute 

Если мы пропустим ключевое слово new, whatIsThis ссылается на самый глобальный контекст, он может найти (window)

С обработчиками событий

Если обработчик события является встроенным, this ссылается на глобальный объект

<script type="application/javascript">
    function click_handler() {
        alert(this); // alerts the window object
    }
</script>

<button id='thebutton' onclick='click_handler()'>Click me!</button>

При добавлении обработчика событий через JavaScript, this относится к элементу DOM, который генерирует событие.


3
ответ дан Community 29 August 2018 в 01:27
поделиться

«Это» - все о сфере видимости. Каждая функция имеет свою собственную область действия, и поскольку все в JS является объектом, даже функция может хранить некоторые значения в себе, используя «это». ООП 101 учит, что «это» применимо только к экземплярам объекта. Поэтому каждый раз, когда выполняет функция, новый «экземпляр» этой функции имеет новое значение «this».

Большинство людей путаются, когда пытаются использовать «это» внутри анонимных функций закрытия например:

(function(value) {
    this.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = this.value;        // uh oh!! possibly undefined
    });
})(2);

Итак, внутри each (), «this» не содержит «значение», которое вы ожидаете от него (от

this.value = value;
над ним). Итак, чтобы справиться с этой проблемой (без каламбуры), разработчик мог:

(function(value) {
    var self = this;            // small change
    self.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = self.value;        // phew!! == 2 
    });
})(2);

попробовать; вам понравится эта схема программирования

43
ответ дан Daniel Alexiuc 29 August 2018 в 01:27
поделиться

Вероятно, самая подробная и всесторонняя статья на this такова:

Нежное объяснение ключевого слова этого «this» в JavaScript

Идея позади this заключается в понимании того, что типы вызова функции имеют важное значение при установке значения this.


Когда возникают проблемы с идентификацией this, не спрашивайте себя:

Где this взято из ?

, но спросите себя:

Как вызывается функция ?

arrow function (специальный случай прозрачности контекста) спросите себя:

Какое значение имеет this, где определена функция стрелки ?

Этот настрой правилен при работе с this и избавит вас от головной боли.

7
ответ дан Dmitri Pavlutin 29 August 2018 в 01:27
поделиться

Здесь является одним из хороших источников this в JavaScript.

Вот сводка:

  • global this In a браузер, в глобальной области, this является объектом window
    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"
    
    В node с использованием repl, this - это верхнее пространство имен. Вы можете ссылаться на него как global.
    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true
    
    В node, выполняемом из сценария, this в глобальной области запускается как пустой объект. Это не то же самое, что global
    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
    
  • функция this

За исключением случаев обработчиков событий DOM или когда предоставляется thisArg (см. ниже), как в узле, так и в браузере с использованием this в функции, которая не вызывается с new, ссылается на глобальную область ...

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

Если вы используете use strict;, в котором case this будет undefined

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      "use strict";
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

Если вы вызываете функцию с new, this будет новым контекстом, он не будет ссылаться на глобальный this.

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"

    console.log(new testThis().foo); //logs "foo"
</script>
  • прототип этого

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

function Thing() {
  console.log(this.foo);
}

Thing.prototype.foo = "bar";

var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

Обычно ошибка заключается в назначении массивов или объектов на prototype. Если вы хотите, чтобы экземпляры каждого имели свои собственные массивы, создайте их в функции, а не в прототипе.

function Thing() {
    this.things = [];
}

var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
  • object this

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

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"
  • DOM event this

В обработчике событий HTML DOM this всегда ссылается на элемент DOM, событие было присоединено к

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}

var listener = new Listener();
document.getElementById("foo").click();

Если вы не bind контекст

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
  • HTML, этот

Внутри атрибутов HTML, в которые вы можете поместить JavaScript, this является ссылкой на элемент.

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
  • eval this

Вы можете использовать eval для доступа к this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();
  • с помощью этого

Вы можете использовать with, чтобы добавить this в текущую область действия, чтобы читать и записывать значения на this, явно не ссылаясь на this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • jQuery this

jQuery во многих местах имеет this ссылается на элемент DOM.

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script>
8
ответ дан gnerkus 29 August 2018 в 01:27
поделиться

Это лучшее объяснение, которое я видел. Понимать JavaScripts это с помощью Clarity

Ссылка эта ALLWAYS означает (и содержит значение) объект - особый объект - и он обычно используется внутри функции или метода, хотя он может использоваться вне функции в глобальной области. Обратите внимание, что когда мы используем строгий режим, это содержит значение неопределенных в глобальных функциях и анонимных функциях, которые не привязаны к какому-либо объекту.

Существуют четыре условия, в которых это может запутать:

  1. Когда мы передаем метод (который использует этот ) в качестве параметра, который будет использоваться в качестве функции обратного вызова.
  2. Другой пример, когда это неправильно понимается, - это когда мы используем внутренний метод (замыкание). Важно отметить, что закрытие не может получить доступ к переменной этой внешней функции внешней функции], используя это ключевое слово, потому что эта переменная доступна только самой функции, а не внутренними функциями.
  3. Используя этот , когда метод присваивается переменной. Значение этого привязано к другому объекту, если мы назначим метод, который использует это для переменной
  4. Используя этот при использовании bind, apply и

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

5
ответ дан James Drinkard 29 August 2018 в 01:27
поделиться
124
ответ дан Jonathan Lin 29 August 2018 в 01:27
поделиться
48
ответ дан Madara Uchiha 29 August 2018 в 01:27
поделиться
4
ответ дан mrmaclean89 29 August 2018 в 01:27
поделиться
1
ответ дан PRADEEP SINGH Chundawat 29 August 2018 в 01:27
поделиться
10
ответ дан RobG 29 August 2018 в 01:27
поделиться

this в Javascript всегда ссылается на «владельца» выполняемой функции.

Если явный владелец не определен, то ссылается на самый верхний владелец - объект окна.

Итак, если бы я сделал

function someKindOfFunction() {
   this.style = 'foo';
}

element.onclick = someKindOfFunction;

this, он ссылался бы на объект элемента. Но будьте осторожны, многие люди делают эту ошибку

<element onclick="someKindOfFunction()">

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

13
ответ дан Seph 29 August 2018 в 01:27
поделиться
1
ответ дан Simon Groenewolt 29 August 2018 в 01:27
поделиться

Трудно получить хорошее представление о JS или написать больше, чем что-либо тривиальное в нем, если вы не понимаете его полностью. Вы не можете просто позволить себе быстро окунуться :) Я думаю, что лучший способ начать работу с JS - сначала посмотреть эти видео-лекции Дугласа Крокфорда - http://yuiblog.com/crockford/ , который охватывает это и то, и все остальное о JS.

4
ответ дан tathagata 29 August 2018 в 01:27
поделиться

Немного информации об этом ключевом слове

Давайте перечислим ключевое слово this на консоль в глобальной области без кода, но

console.log(this)

В Client / Browser this ] - глобальный объект, который является window

console.log(this === window) // true

и

В ключевом слове Server / Node / Javascript this также является глобальным объектом, который является module.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

Имейте в виду, что exports - это просто ссылка на module.exports

1
ответ дан unclexo 29 August 2018 в 01:27
поделиться

Резюме this Javascript:

  • Значение this определяется тем, как функция вызывается не, где она была создана!
  • Обычно значение из this определяется Объектом, который остается от точки. (window в глобальном пространстве)
  • В случае прослушивателей значение this относится к элементу DOM, на котором было вызвано событие.
  • Когда функция вызывается с помощью new ключевое слово значение this относится к вновь созданному объекту
  • Вы можете управлять значением this с помощью функций: call, apply, bind

Пример:

let object = {
  prop1: function () {console.log(this);}
}

object.prop1();   // object is left of the dot, thus this is object

const myFunction = object.prop1 // We store the function in the variable myFunction

myFunction(); // Here we are in the global space
              // myFunction is a property on the global object
              // Therefore it logs the window object
              
             

Пример прослушивателей событий:

document.querySelector('.foo').addEventListener('click', function () {
  console.log(this);   // This refers to the DOM element the eventListener was invoked from
})


document.querySelector('.foo').addEventListener('click', () => {
  console.log(this);  // Tip, es6 arrow function don't have their own binding to the this v
})                    // Therefore this will log the global object
.foo:hover {
  color: red;
  cursor: pointer;
}
<div class="foo">click me</div>

Пример конструктора:

function Person (name) {
  this.name = name;
}

const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object

console.log(me.name); 
// Therefore, the name property was placed on the object created with new keyword.

0
ответ дан Willem van der Veen 29 August 2018 в 01:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: