2015-05-19 10 views
5

Tôi tìm thấy mã ví dụ này:Cách "này" hoạt động trong các hàm được gán trong hàm tạo?

function personFullName() { 
    return this.first + ' ' + this.last; 
} 

function Person(first, last) { 
    this.first = first; 
    this.last = last; 
    this.fullName = personFullName; 
} 

var dude = new Person("Michael", "Jackson"); 
alert(dude.fullName()); 

Cảnh báo nào "Michael Jackson". Tôi đã thay đổi nó để gọi personFullName từ các nhà xây dựng thay vì gán đối tượng chức năng:

function personFullName() { 
    return this.first + ' ' + this.last; 
} 

function Person(first, last) { 
    this.first = first; 
    this.last = last; 
    this.fullName = personFullName(); 
} 

var dude = new Person("Michael", "Jackson"); 
alert(dude.fullName); 

tôi mong chờ các "FullName" bất động sản đến nay là một chuỗi thay vì một hàm. Nhưng bây giờ nó cảnh báo "undefined undefined". Bất cứ ai có thể giải thích lý do tại sao phiên bản của tôi không hoạt động?

+5

Xem câu trả lời này để biết giải thích đầy đủ về cách thức hoạt động của 'this': http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object -literal/13441628 # 13441628 – slebetman

Trả lời

6

Trong JavaScript, this thường là bất kỳ điều gì xảy ra trước số . trong cuộc gọi hàm. Vì vậy, thực tế là bạn đã nói dude.fullName() là nguyên nhân gây ra this trong fullName() để được đặt thành dude .

Trong phiên bản thứ hai trong câu hỏi của bạn, bạn không gọi nó theo cùng một cách. Bạn đang gọi số personFullName() mà không có bất kỳ thứ gì ở phía trước (đúng là vì nó không còn được gắn với đối tượng Person) nữa. Điều đó có nghĩa là this kết thúc mặc định với cùng một giá trị như window. Vì window không có thuộc tính first hoặc last được đặt trên đó, this.firstthis.lastundefined.

Để sửa lỗi này, bạn có thể làm cho người bạn có một cuộc tranh cãi với personFullName() chức năng:

function personFullName(person) { 
    return person.first + ' ' + person.last; 
} 

và sau đó gọi nó như

… 
this.fullName = personFullName(this); 

1: Note rằng phương thức phải là một thuộc tính trên đối tượng cho ràng buộc this hoạt động. Bạn không thể chỉ gọi số object.someMethod() và nhận được this được đặt thành object trong someMethod. Trong mã của bạn, sau đây sẽ không hoạt động:

function Person(first, last) { 
    this.first = first; 
    this.last = last; 
    this.fullName = this.personFullName(); 
} 

Uncaught TypeError: this.personFullName is not a function

Cả sẽ này:

function personFullName() { 
    return this.first + ' ' + this.last; 
} 

function Person(first, last) { 
    this.first = first; 
    this.last = last; 
} 

var dude = new Person("Michael", "Jackson"); 
alert(dude.personFullName()); 

Uncaught TypeError: dude.personFullName is not a function

Bạn có thể khắc phục hạn chế này trong mọi tình huống với apply phương thức trợ giúp: this.fullName = personFullName.apply(this) làm những gì bạn mong đợi phiên bản thứ hai của mã của bạn để làm và y bạn cũng có thể gọi số personFullName.apply(dude) tại bất kỳ thời điểm nào và nhận lại số "Michael Jackson".

1

this là cửa sổ trong hàm personFullName vì nó không được gọi trong ngữ cảnh chính xác. Bạn có thể sử dụng apply để gọi nó với ngữ cảnh chính xác mà không cần sửa đổi chức năng personFullName.

function personFullName() { 
    return this.first + ' ' + this.last; 
} 

function Person(first, last) { 
    this.first = first; 
    this.last = last; 
    this.fullName = personFullName.apply(this); // The magic 
} 

var dude = new Person("Michael", "Jackson"); 
alert(dude.fullName); 
1

Một lựa chọn tốt hơn để khắc phục điều đó sẽ là:

Person.prototype.personFullName = function() { 
    return this.first + ' ' + this.last; 
} 
0

Bối cảnh trong đó bạn đang truy cập this trong ví dụ thứ hai của bạn, được tham chiếu đến đối tượng window. window không có thuộc tính fullName được đặt. Nếu bạn thêm vào cả hai hàm bạn sẽ thấy ý tôi.

Các vấn đề liên quan