2016-06-15 1 views
1

я следующий фрагмент кодаJavascript новый с твердый переплет

function foo(a) { 
 
    this.a = a; 
 
} 
 

 
var obj = {a: 77}; 
 

 
var bar = function() { 
 
    return foo.apply(obj, arguments); 
 
}; 
 

 
var o = new bar(2); 
 

 
console.log(o.a); // I think it's 2(why is it undefined?) 
 
console.log(obj.a); // obj.a changed to 2, got it.

Почему o.a не определено? также, если я удалю ключевое слово return в bar, он все равно будет таким же.

function foo(a) { 
 
    this.a = a; 
 
} 
 

 
var obj = {a: 77}; 
 

 
var bar = function() { 
 
    foo.apply(obj, arguments); 
 
}; 
 

 
var o = new bar(2); 
 

 
console.log(o.a); // I think it's 2(why is it undefined?) 
 
console.log(obj.a); // obj.a changed to 2, got it.

Вопрос на самом деле то, что происходит, когда твердый переплет и новое связывание происходит то же самое время

+0

Возможно, 'return new foo.apply (obj, arguments);' и 'var o = bar (2);' вместо 'var o = new bar (2);'? – Xufox

+0

Я не совсем уверен, что вы просите.Вы никогда не используете 'this' внутри' bar', поэтому зачем 'o' устанавливать какие-либо данные? – zzzzBov

+0

'return new (foo.bind.apply (foo, [null] .concat ([]. Slice.call (arguments)))); var o = bar (2) '. Вы можете сделать это более легко в ES6. – elclanrs

ответ

1

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

Что касается того, почему добавление и удаление return ничего не меняет, так как в обоих случаях вы возвращаете undefined. Когда функция вызывается с new и возвращает undefined (a.k.a значение возврата по умолчанию), он возвращает новый объект, сгенерированный new.

Цитирую MDN:

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

Таким образом, вы создаете новый объект, но управляете старым объектом. Ваш код работает так.

function foo(a) { 
 
    this.a = a; 
 
} 
 

 
var obj = {a: 77}; 
 

 
var bar = function() { 
 
    return foo.apply(obj, arguments); 
 
}; 
 

 
var o = {}; // Originally you used `new` to create a new object 
 
bar(2); // Since `bar` doesn't use `this`, it's the same as if it were called by itself 
 

 
console.log(o.a); // Empty object 
 
console.log(obj.a); // Modified by `bar`

1

Вы должны вернуть this из foo(a), например, так:

function foo(a) { 
 
    this.a = a; 
 
    // "this" NEEDS TO BE RETURNED, OTHERWISE (bar)'s 
 
    // VALUE WILL BE UNDEFINED, THUS o.a WILL BE UNDEFINED 
 
    return this; 
 
} 
 

 
var obj = {a: 77}; 
 

 
var bar = function() { 
 
    // MAKE SURE THIS IS RETURNED AS WELL 
 
    return foo.apply(obj, arguments); 
 
}; 
 

 
var o = new bar(2); 
 

 
console.log(o.a); // I think it's 2(why is it undefined?) 
 
console.log(obj.a); // obj.a changed to 2, got it.

Вопрос на самом деле то, что происходит, когда жесткий привязки ING и новый связывание происходит то же самое время

В этом случае ничего, потому что новый экземпляр new bar(2) бесполезен, когда его возвращаемое значение зависит от foo(a) и foo(a) зависит от одноточечного (obj).

Я надеюсь, что это поможет!