2015-01-09 26 views
2

爲了探索使用此標識符的函數的javascript作用域規則 ,我編寫了以下代碼段。我期望person.helloFunk()的第二個調用 打印名稱「Marvin」和年齡「非常非常古老」,因爲我 在函數對象本身上創建了屬性navn和age,但事實並非如此。 代替它重複相同的輸出「你好,我是zaphod,我42歲」。 那麼爲什麼它是指函數所嵌入的對象,而不是函數本身(它也是一個對象)?使用此標識符的函數的javascript作用域規則

var sayHello = function() { 
    return "Hello, I'm " + this.navn + " and I'm " + this.age + " years old."; 
} 
var person = {navn: 'zaphod', age: 42}; 
person.helloFunk = sayHello; 
console.log(person.helloFunk()); 

sayHello.navn = 'Marvin'; 
sayHello.age = 'verry verry old'; 
console.log(person.helloFunk()); 
console.log(person.helloFunk.navn); 
console.log(person.helloFunk.age); 

回答

1

您正在設置該功能的成員而不是人員對象。 如果您設置了thoe person對象的成員,則該函數中的「this」將引用正確的數據。 person.navn ='馬文' console.log(person.helloFunk());//將打印輸出「你好,我是馬文,我42歲。」

0

簡單的答案是,"because that is the way JavaScript is supposed to work"this是動態的並且相對於容器來解析(如果沒有其他容器,則爲global|window,除非在嚴格模式下,在這種情況下它是undefined)。

如果你想變化什麼this點,你可以使用callapply,或bind

// call and apply differ only in how you pass arguments 
// In this case, no arguments, so the invocation is the same 
person.helloFunk.call(sayHello); 
person.helloFunk.apply(sayHello); 

var boundHello = person.helloFunk.bind(sayHello); 
boundHello(); 
+0

我認爲將函數('sayHello')作爲上下文傳遞給'call','apply'和'bind'實際上是一個壞主意,也是一個壞例子。它應該是該函數用作「this」的對象。 – Ziarno 2015-01-09 21:57:25

+0

@Ziarno - 在這種情況下,它已經添加了必要的數據 - 而且函數*畢竟是JavaScript中的一個對象。 'sayHello instanceof Object === true' – 2015-01-09 22:04:47

0

this不指向函數本身,而是調用它的對象。

function sayHello() { 
    return this.hello; 
} 

sayHello.hello = "hi!"; 

console.log(sayHello()); //undefined 

當您嘗試運行這段代碼:

var sayHello = function() { 
    return "Hello, I'm " + this.navn + " and I'm " + this.age + " years old."; 
} 

sayHello.navn = 'Marvin'; 
sayHello.age = 'verry verry old'; 

var person = {navn: 'zaphod', age: 42}; 
person.helloFunk = sayHello; 
console.log(person.helloFunk()); 

thisperson,不sayHello