2016-03-26 1 views
-1

Пытаясь понять «это» ключевое слово в JavaScript, я смотрел на многих ресурсах, в том числе ответы на этот популярный переполнением стека вопрос: How does the "this" keyword work?Почему «это» обрабатывается по-разному при использовании с объектами функций?

Я не знаю, если я что-то недоразумение, но все, что я прочитал, кажется неполным и отсутствует правило: Хотя функции являются объектами, «это» обрабатывается по-разному для объектов-объектов по сравнению с другими объектами.

Рассмотрим следующий код:

var object = {}; 
object.name = "object"; 
object.logMyName = function() { 
    console.log(this.name); 
}; 
object.logMyName(); 

Поскольку функция («logMyName») вызывается на объект («объект»), «этот» установлен в положение объекта («объект»), на которой вызывается функция ('logMyName').

Теперь рассмотрим следующий код:

var funcObject = function() {}; 
funcObject.name = "funcObject"; 
funcObject.logMyName = function() { 
    console.log(this.name); 
}; 
funcObject.logMyName(); 

Хотя функция ('logMyName') был вызван на объект ('funcObject'), 'это' является не набор к объекту ('funcObject '), на который была вызвана функция (' logMyName ').

Почему это несоответствие между типами объектов существует и почему это редко или никогда не обсуждалось?

+1

2-й пример кода использует анонимную функцию. Когда я отбрасываю этот код в jsfiddle, то «this.name» возвращается пустым. Свойство name отображается только для чтения и не может быть установлено с помощью функции funcObject.name = funcObject, ' – Clomp

ответ

5

Это потому, что функции имеют специальное свойство name.

Значение name свойства является строка, которая является описательной функции . Имя не имеет семантического значения, но обычно это переменная или имя свойства , которая используется для ссылки на функцию в ее точке определения в коде ECMAScript. Это свойство имеет атрибуты {[[Writable]]: ложные, [[Enumerable]]: ложные, [[Настраиваемый]]: верно}.

Это свойство не доступно для записи, поэтому ваше задание игнорируется.

Однако, так как это настраивается, вы можете переопределить его:

var funcObject = function() {}; 
Object.defineProperty(funcObject, 'name', { 
    configurable: true, 
    value: "funcObject" 
}); 
funcObject.logMyName = function() { 
    console.log(this.name); 
}; 
funcObject.logMyName(); // logs "funcObject" 

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

+0

Вы правы. Я думал, что это был признак «этого» поведения, но кажется, что это просто из-за свойств только для чтения. Я не знал, что JavaScript имеет такую ​​вещь, как свойства только для чтения. Который к сожалению терпит неудачу. – cowlinator

+1

@cowlinator еще одна веская причина использовать строгий режим: P – lifetimes

Смежные вопросы