2015-03-30 2 views
2

Я просто играл с JavaScript и создавал конструкторы, и я наткнулся на этот недоумение.Экземпляр класса, возвращающий функцию

var foo = function(){ 
    this.x = 1; 
    return function(){ 
     return this.x; 
    } 
} 
var x = new foo(); 
console.log(x); 

я выполнил следующие действия для этого:

console.log(x); // The given output is expected for this line of code 
console.log(x()); 
console.log(x()()); 
console.log(x()()()); 

Все вышеперечисленное дал мне тот же результат, как следующее:

function(){ 
    return this.x; 
} 

Может кто-нибудь объяснить, что происходит в коде выше , Я не мог дать правильное название для этого вопроса. Извини за это.

Примечание: Я знаю конструкторы в JS. И вышеупомянутый код был просто из любопытства.

ответ

4

Чтобы сделать длинную историю короткой - это не делает ничего полезного.

Если конструктор возвращает объект, то значение, выражаемое выражением new, является значением, а не построенным объектом. Поэтому вместо получения экземпляра foo вы получаете функцию, которая возвращает this.x.

Похоже, что этот код пытается создать функцию, которая возвращает значение this.x созданного объекта, но это не то, что он делает. Так как вы звоните x() сам по себе, this.x на самом деле ссылается на переменную x, поэтому независимо от того, сколько раз вы звоните x()()(), она просто возвращается сама.

Если вы использовали любое имя переменной, кроме x и не создавали x переменную (например y), то y() бы просто вернуть undefined и y()() будет производить ReferenceError.

Это также потерпело бы неудачу намного раньше в строгом режиме, потому что в функции функция ссылалась бы на undefined, когда вы пытались ее назвать.

+0

Urghh ... Я должен был немного подумать. Еще спасибо. – Mahesh

0

Моя интерпретация такова: x содержит результат вызова функции foo().

Foo() возвращает функцию:

function(){ 
     return this.x; 
} 

тело этой функции записывается в консоль

+0

Тогда почему призывающие 'х()()()()()' будет возвращать тело функции? –

+1

@ArtyomNeustroev, который терпит неудачу с ошибкой 'Uncaught TypeError: undefined не является функцией' - http://jsfiddle.net/arunpjohny/pbm2k37y/2/ –

+1

@ArunPJohny вызывает ошибку при запуске внутри консоли DevTools? Потому что это не для меня. –

0

Вот пример с предыдущим ответом, который демонстрирует это:

var x = 5; 
var foo = function(){ 
    this.x = 1; 
    return function(){ 
     return this.x; 
    } 
} 
var b = new foo(); 
b() //--> 5 
0

Этот код все о контексте функции вызова.

Во время выполнения this ссылки в this.x = 1; привязано к другому объекту, чем this ссылки в return this.x;

x() вызывает анонимную функцию, возвращенную обув, в глобальном контексте.Для среды ECMAScript 3 (и более ранней) глобальная функция вызова контекста связывает глобальный объект с this внутри вызываемой функции. Таким образом, return this.x; ссылается на var x, который вы определяете на глобальном объекте.

В инструкции ECMAScript 5, use strict; оператор может быть помещен в любое объявление функции, чтобы отключить привязку глобального объекта «этим» способом.

Анонимные, вложенные функции могут получить доступ к "Foo в" this в затворе:

var foo = function(){ 
    this.x = 1; 
    var that = this; 
    return function(){ 
     return that.x; 
    } 
} 
var x = new foo(); 
console.log(x); // function(){ ... 
x(); // 1 
Смежные вопросы